Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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!

like image 787
JackWM Avatar asked Jul 16 '12 05:07

JackWM


People also ask

How can we pause the execution of a thread for specific time?

Thread. sleep() method can be used to pause the execution of current thread for specified time in milliseconds.

Does sleep pause all threads?

Method Whenever Thread. sleep() functions to execute, it always pauses the current thread execution. If any other thread interrupts when the thread is sleeping, then InterruptedException will be thrown.

Which causes the current thread to suspend execution for a specified period?

sleep causes the current thread to suspend execution for a specified period. This is an efficient means of making processor time available to the other threads of an application or other applications that might be running on a computer system.


Video Answer


2 Answers

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); } 
like image 151
qwerty Avatar answered Sep 28 '22 21:09

qwerty


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 microseconds. There is no point trying to suspend a thread for less time than 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.

like image 30
Peter Lawrey Avatar answered Sep 28 '22 21:09

Peter Lawrey