简体   繁体   中英

Java thread sleep() method

I am doing a past exam paper of Java, I am confused about one question listed below:

What would happen when a thread executes the following statement in its run() method? (Choose all that apply.)

sleep(500);

A. It is going to stop execution, and start executing exactly 500 milliseconds later.

B. It is going to stop execution, and start executing again not earlier than 500 milliseconds later.

C. It is going to result in a compiler error because you cannot call the sleep(…) method inside the run() method.

D. It is going to result in a compiler error because the sleep(…) method does not take any argument.

I select A,B. but the key answer is only B, does there exist any circumstances that A could also happen? Could anyone please clarify that for me? Many thanks.

JVM cannot guarantee exactly 500 ms but it will start on or after ~500 ms as it will need to start its 'engine' back considering no other threads are blocking any resources which may delay a bit.

Read: Inside the Hotspot VM: Clocks, Timers and Scheduling Events

Edit: As Gray pointed out in the comment - the scheduling with other threads also a factor, swapping from one to another may cost some time.

I select A,B. but the key answer is only B, does there exist any circumstances that A could also happen? Could anyone please clarify that for me?

Yes, depending on your application, you certainly might get 500ms of sleep time and not a nanosecond more.

However, the reason why B is the better answer is that there are no guarantees about when any thread will be run again. You could have an application with a large number of CPU bound threads. Even though the slept thread is now able to be run, it might not get any cycles for a significant period of time. The precise sleep time also depends highly on the particulars of the OS thread scheduler and clock accuracy. Your application also may also have to compete with other applications on the same system which may delay its continued execution.

For example, this following program on my extremely fast 8xi7 CPU Macbook Pro shows a max-sleep of 604ms:

public class MaxSleep {

    public static void main(String[] args) throws Exception {
        final AtomicLong maxSleep = new AtomicLong(0);
        ExecutorService threadPool = Executors.newCachedThreadPool();
        // fork 1000 threads
        for (int i = 0; i < 1000; i++) {
            threadPool.submit(new Runnable() {
                @Override
                public void run() {
                    for (int i = 0; i < 10; i++) {
                        long total = 0;
                        // spin doing something that eats CPU
                        for (int j = 0; j < 10000000; j++) {
                            total += j;
                        }
                        // this IO is the real time sink though
                        System.out.println("total = " + total);
                        try {
                            long before = System.currentTimeMillis();
                            Thread.sleep(500);
                            long diff = System.currentTimeMillis() - before;
                            // update the max value
                            while (true) {
                                long max =  maxSleep.get(); 
                                if (diff <= max) {
                                    break;
                                }
                                if (maxSleep.compareAndSet(max, diff)) {
                                    break;
                                }
                            }
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            });
        }
        threadPool.shutdown();
        threadPool.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
        System.out.println("max sleep ms = " + maxSleep);
    }
}

According to Javadoc :-

Sleep()

Causes the currently executing thread to sleep (temporarily cease execution) for the specified number of milliseconds, subject to the precision and accuracy of system timers and schedulers. The thread does not lose ownership of any monitors.

So it may be ~500ms

B. It is going to stop execution, and start executing again not earlier than 500 milliseconds later.

Looks more prominent.

These sleep times are not guaranteed to be precise, because they are limited by the facilities provided by the underlying OS. Option B: Not earlier than 500 is more correct.

You cannot select A and B as they are opposite to each other, the main difference: exactly 500 milliseconds later and not earlier than 500 milliseconds later

first mean exactly what it means (500 milliseconds only), second means that it can sleep 501 or 502 or even 50000000000000

next question - why B is true, it is not so simply question, you need to understand what is the different between hard-realtime and soft-realtime, and explaining of all reasons is quite offtopic, so simply answer - because of many technical reasons java cannot guarantee hard real time execution of your code, this is why it stated that sleep will finish not earlier than ...

you can read about thread scheduling, priorities, garbage collection, preemptive multitasking - all these are related to this

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM