Search code examples
javamultithreadingsleep

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.


Solution

  • 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);
        }
    }