-3

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?

Nfernandez
  • 646
  • 1
  • 5
  • 16

4 Answers4

3

"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()

Solomon Slow
  • 25,130
  • 5
  • 37
  • 57
  • Your example is broken due to long overflow. – pveentjer Sep 29 '21 at 03:54
  • @pveentjer, Thank you. I changed my example. To be honest, I don't know how for certain how modern Java deals with numeric overflow, but the logic in my new example is exactly what I have done many times in decades past in embedded C programs using _16-bit_ ints and a counter that (in some cases) overflowed more than once per minute. Even in spite of the overflow, the subtraction always gave a useful result. But that was before the C standards committee invented "undefined behavior" and gave compiler writers license to optimize away code that depended on it. – Solomon Slow Nov 05 '21 at 17:28
  • I'm also not an expert. I always check the documentation and apply the example provided in the Javadoc. – pveentjer Nov 06 '21 at 03:51
0

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

0

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.

pveentjer
  • 10,545
  • 3
  • 23
  • 40
0

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.

Rick314
  • 11
  • 4