简体   繁体   中英

Order of execution and Thread.sleep

Recently I've seen some code which depends on order of execution in different threads which was achieved by calling Thread.sleep with some values. It worked without any problems but I'm sure that in some rare cases it would not. I wrote some code where order of output depends on how precisely Thread.sleep works.

public class Test {
    public static Thread createDelayedPrintThread(final String text,
            final long delay) {
        return new Thread() {
            public void run() {
                try {
                    Thread.sleep(delay);
                    System.out.print(text);
                } catch (InterruptedException e) {
                }
            }
        };
    }

    public static void main(String[] args) {
        Thread t1 = createDelayedPrintThread("t1", 10);
        Thread t2 = createDelayedPrintThread("t2", 10);
        t1.start();
        t2.start();
    }
}

This code obliviously can output booth t1t2 and t2t1 so I made delays different:

Thread t1 = createDelayedPrintThread("t1", 10);
Thread t2 = createDelayedPrintThread("t2", 20);

Now it outputs t1t2 but I still sometimes get t2t1 . It usually happens when I do some CPU/IO intensive operations.
If I change delays to extremely big values

Thread t1 = createDelayedPrintThread("t1", 1_000); // one second
Thread t2 = createDelayedPrintThread("t2", 60_000); // one minute

would be there any guarantees that the application will output t1t2 ?

Thread.sleep is not guarantees. Java tutorial, about Thread.sleep():

"However, these sleep times are not guaranteed to be precise, because they are limited by the facilities provided by the underlying OS. Also, the sleep period can be terminated by interrupts, as we'll see in a later section. In any case, you cannot assume that invoking sleep will suspend the thread for precisely the time period specified."

So, you need add other multithreading logic for guarantees execution order.

First, your understanding is correct; no amount of Thread.sleep() (and by the way, since Java 5 you should really be using TimeUnit instead, as in TimeUnit.SECONDS.sleep(2L) ) will guarantee in-order execution; you cannot guarantee when the OS will schedule this or that thread.

would be there any guarantees that the application will output t1t2?

Yes.

For instance, a volatile boolean variable shared by those two threads will do (although you'll need to busy wait so this is not ideal). Another example is a Semaphore .

Solutions are many, and what you will end up with depends entirely upon your requirements.

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