Thread.Sleep for Less Than 1 Millisecond

Thread.Sleep for less than 1 millisecond

You can't do this. A single sleep call will typically block for far longer than a millisecond (it's OS and system dependent, but in my experience, Thread.Sleep(1) tends to block for somewhere between 12-15ms).

Windows, in general, is not designed as a real-time operating system. This type of control is typically impossible to achieve on normal (desktop/server) versions of Windows.

The closest you can get is typically to spin and eat CPU cycles until you've achieved the wait time you want (measured with a high performance counter). This, however, is pretty awful - you'll eat up an entire CPU, and even then, you'll likely get preempted by the OS at times and effectively "sleep" for longer than 1ms...

Thread.Sleep(1) takes longer than 1ms

Timers other than Stopwatch are incremented by the clock interrupt. Which by default ticks 64 times per second on Windows. Or 15.625 milliseconds. So a Thread.Sleep() argument less than 16 doesn't give you the delay you are looking for, you'll always get at least that 15.625 interval. Similarly, if you read, say, Environment.TickCount or DateTime.Now and wait less than 16 millisecond then you'll read the same value back and think 0 msec has passed.

Always use Stopwatch for small increment measurements, it uses a different frequency source. Its resolution is variable, it depends on the chipset on the motherboard. But you can rely on it being better than a microsecond. Stopwatch.Frequency gives you the rate.

The clock interrupt rate can be changed, you have to pinvoke timeBeginPeriod(). That can get you down to a single millisecond and actually make Thread.Sleep(1) accurate. Best not to do this, it is very power unfriendly.

Pause a thread for less than one millisecond

Send 20 messages and then sleep for 1 millisecond?

You can't sleep for less than the scheduler quantum, unless you have a hardware interrupt other than the system timer. Read the answers in the question you linked, they explain why the suggested approach doesn't actually work.

Even with this approach you might sleep longer than 1ms, or since the messages aren't sent instantaneously, the whole operation will surely take longer than 1ms, reducing the overall rate.

So, inspect a precision clock source every time you wake, and calculate how many messages to send based on elapsed time, don't use a constant 20.

Can a Thread sleep for less than half milli seconds in Java/ Other language?

You can use LockSupport's parkNanos

LockSupport.parkNanos(400_000);

however this is not the same as sleep (it is not interruptable) and all it does is pass the request to the OS. On Windows 8 for example, even parkNanos(1) might sleep for 1 milli-second.

As biziclop pointed out, there Javadoc mentions

The call spuriously (that is, for no reason) returns.

This happens rarely in my experience, but it does happen.


However, you are right that Thread.sleep() will always sleep for at least 1 ms. On Win XP it might sleep for 16 ms (1/60th of a second)

Also what would guarantee that the thread wakes up accurately?

Using a real time operating system.

What I do, is don't go to sleep but rather busy wait. This way I can stop for a give amount of time with more accuracy. If you run your thread on an isolated CPU (In Linux) you can reduce the variation to about 10 micro-seconds

An example of busy waiting

long end = System.nanoTime() + delay;
while (System.nanoTime() < end) { /* busy waiting */ }

or if you want to be slightly more friendly

while (System.nanoTime() < end) 
Thread.yield();

Timer: period less than a millisecond

If you want to sleep, Thread.sleep has 2 methods, one of which accepts nanoseconds. If you want to schedule a task, you can use a ScheduledExecutorService which schedule methods can use nanoseconds too.

As explained by @MarkoTopolnik, the result will most likely not be precise to the nanosecond.

How to sleep a thread in java for few milliseconds?

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

Java thread.sleep(1) sleeping longer than 1 ms

The sleep() method in java puts the currently executing thread (in the running state) to sleep for 1 ms.

After 1 ms the thread comes to runnable state (able to run), now it depends on the scheduler when to take the thread from the runnable state and execute it (i.e, running state).

For this reason, you can assume that the thread sleeps for a minimum of 1ms before running again.

Below figure describes the different thread states:
Sample Image

When does Thread.sleep(1000) sleeps less than 1000 milliseconds?

According to this (Implementation of the sleep by windows operating system, which is what Thread.sleep will call underneath): If dwMilliseconds is less than the resolution of the system clock, the thread may sleep for less than the specified length of time. If dwMilliseconds is greater than one tick but less than two, the wait can be anywhere between one and two ticks, and so on. To increase the accuracy of the sleep interval, call the timeGetDevCaps function to determine the supported minimum timer resolution and the timeBeginPeriod function to set the timer resolution to its minimum.



Related Topics



Leave a reply



Submit