How to suspend a java thread for a small period of time, like 100 nanoseconds?

余生颓废 提交于 2019-12-17 18:50:13

问题


I know Thread.sleep() can make a java thread suspend for a while, like certain milliseconds and certain nanoseconds. But the problem is the invocation of this function also causes overhead.

For example, if I want a thread to suspend for 100 nanoseconds, and I call Thread.sleep(0, 100). The whole cost for this process is invocation_cost + 100 nanosceonds, which may be much larger the what I want. How could I avoid this problem, and achieve my purpose?

The reason I need this is that I want to do simulation offline. I profiled the execution time of a task; Now I want to simulate this execution time by suspending a thread in the same time period.

Thanks!


回答1:


The granularity of sleeps is generally bound by the thread scheduler's interrupt period. In Linux, this interrupt period is generally 1ms in recent kernels. In Windows, the scheduler's interrupt period is normally around 10 or 15 milliseconds

If I have to halt threads for periods less than this, I normally use a busy wait

EDIT: I suspect you'll get best results on jrockit + solaris. The numbers on a windows box are terrible.

@Test
public void testWait(){
    final long INTERVAL = 100;
    long start = System.nanoTime();
    long end=0;
    do{
        end = System.nanoTime();
    }while(start + INTERVAL >= end);
    System.out.println(end - start);
}



回答2:


For simulation I would not attempt to simulate in real time as this doesn't give you reproducible results. i.e. you can't test your simulation.

Instead I would use a data driven, simulated clock and run everything as fast as possible. This gives you reproducible results and allows you to simulate faster than real time (e.g. 2x to 100x faster)


Suspecting a thread takes around 10 micro-seconds. There is no point try to suspend a thread for less time that this.

To busy wait for a short period of time you can try.

long start = System.nanotime();
while(start + delay >= System.nanoTime());

Note: as @EugeneBeresovsky comments, after your machine has been running for 292 years this could overflow so you might choose to write this as

while(System.nanoTime() - start < delay);

This will fine for delays of less than 292 years instead. You can use System.currentTimeMillis() for much longer delays.

However, even this is not reliable as System.nanoTime() can take up to 300 ns on Centos 5.x so calling it twice is going to take much longer than 100 ns. Also many OS only have a resolution of 1000 ns (1 micro-second) so this loop will wait up to 1 micro-second regardless of the delay you are looking for.

Instead what you can do is to busy wait in a short loop which is not optimised way.

For a delay of 100 ns, I suspect it would be better to busy wait on whatever you are waiting for instead of creating a separate busy loop.




回答3:


public static void busySleep(long nanos)
{
  long elapsed;
  final long startTime = System.nanoTime();
  do {
    elapsed = System.nanoTime() - startTime;
  } while (elapsed < nanos);
}



回答4:


One more problem with Thread.sleep() is that it is not guaranteed to wakeup after the specified time. A sleeping thread is guarenteed to sleep for the specified nano/micro seconds but not guarenteed to wakeup immediately after that. Since you are talking interms of nanoseconds, you might want to try Object.wait(long, int).

I ve been quite consistent with the order of 10s of nanoseconds with the above method.




回答5:


Do a busy wait , ( ie have a while loop cycle through so many numbers doing nothing ). A the start of your program you can time the amount of time it took it execute this busy wait and increase or decrease it to get to 5 nano seconds

I have found object.wait gets hairy with this frequency also make note that a busy wait solution would most likely be machine dependent Hence why you should have a calibration step at the start of your program




回答6:


Suppose a producer thread is filling a work buffer, say a linked list. The buffer can be sized so it does not empty in less than a sleep-wake period, and the cpu can support the consumer threads that empty the buffer while you sleep. You might even up the buffer size until it is not empty when you wake. Now, how much sleep is a business decision, as there is switching overhead. Lots of hints on figuring that in the above!

Of course, there are several Blocking Concurrent Classes but generally their capacity is fixed. Blocking is no less expensive a thread suspend, I have to believe.



来源:https://stackoverflow.com/questions/11498585/how-to-suspend-a-java-thread-for-a-small-period-of-time-like-100-nanoseconds

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!