'How to sleep a thread in java for few milliseconds?
I would like to sleep a thread for 1ms. I used to implement the sleep in java code with Thread.sleep(x) being x the amout of milliseconds that I want to sleep. However, I saw that it won't work with few amount of milliseconds (1 ms) because sleep relinquishes the thread's timeslice. That is, the minimum amount of time a thread will actually stall is determined by the internal system timer but is no less than 10 or 25ms (depending upon OS).
Is there any way to implement it for few milliseconds e.g. 10 ms or 1 ms?
Solution 1:[1]
"Relinquish the thread's timeslice" and "sleep" both mean approximately the same thing. If you want a delay that does not "sleep," then you need your thread to "spin," doing nothing, for that amount of time. E.g.,
static void spin(long delay_in_milliseconds) {
long delay_in_nanoseconds = delay_in_milliseconds*1000000;
long start_time = System.nanoTime();
while (true) {
long now = System.nanoTime();
long time_spent_sleeping_thus_far = now - start_time;
if (time_spent_sleeping_thus_far >= delay_in_nanoseconds) {
break;
}
}
}
A call to spin(n)
will burn CPU time for n
milliseconds, which is the only way to delay a thread without "relinquishing the time slice."
P.S., You said, "I saw that it [sleep()
] won't work..." Why is that? What did you see? Did you actually measure the performance of your program, and find that it is not satisfactory? or is your program failing to meet some hard real-time requirement? If your program has real-time requirements, then you might want to read about the "Real-time Specification for Java" (RTSJ).
See Also, https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/lang/System.html#nanoTime()
Solution 2:[2]
I don't think the os will let you do that. My best bet is to do, maybe a small loop that would consume some time. But then also be beware of the java compiler as it may and can eliminate pointless loops by performing dead code analysis. So just store the result of the loop and in the loop, perform some divisions or modulos, these are great for consuming time.
But overall, its all a hack, and you should generally refrain from doing such small delays. Typically they do not improve user experience but still result in convoluted code
Solution 3:[3]
Like the other posters already mentioned, you don't get a lot of control. Especially not with the Thread.sleep. A method that is slightly more reliable is the LockSupport.parkNanos. That should give you granularity of at least 50 us on Linux.
For more information see this excellent post.
Also keep in mind that if other processes are running, it is easy to get multi ms pauses. Interrupt processing can also cause a lot of disturbance. And of course, the Java GC and various other aspects of the JVM like (re)jitting, biased lock revocation, callstack sampling (depending on the mechanism) etc can be a cause of pauses as well.
Solution 4:[4]
If the needed delay is in a loop and only the average delay per loop is important consider using the OS time measurement (e.g. System.nanotime()) to measure a sleep() delay and then call sleep() every nth loop to average the correct fraction of a ms. For example sleep(1) every 3rd loop averages 1/3 of whatever sleep(1) delays. A measurement of overall delay can be kept along with total loop count so the average delay per loop is known. Then periodic corrections can also be included.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Sayantan Chakraborty |
Solution 3 | |
Solution 4 |