Are Thread.sleep(0) and Thread.yield() statements equivalent?

后端 未结 12 1632
太阳男子
太阳男子 2020-11-27 02:42

Are these two statement equivalent?

Thread.sleep(0);
Thread.yield();
相关标签:
12条回答
  • 2020-11-27 03:17

    No, they are not equivalent and besides the explanations above, I think it's necessary to check the Javadoc of yield. It seems not a good idea to use yield unless below situation meets.

     It is rarely appropriate to use this method. It may be useful
     for debugging or testing purposes, where it may help to reproduce
     bugs due to race conditions. It may also be useful when designing
     concurrency control constructs such as the ones in the
     {@link java.util.concurrent.locks} package.
    
    0 讨论(0)
  • 2020-11-27 03:20

    Thread.sleep() and Thread.yield() do the same thing except that Thread.yield() relinquishes only to threads running on the same processor in multiprocessor environment.

    0 讨论(0)
  • 2020-11-27 03:21

    What yield() is supposed to do is make the currently running thread head back to runnable to allow other threads of the same priority to get their turn. So the intention is to use yield() to promote graceful turn-taking among equal-priority threads. In reality, though, the yield() method isn't guaranteed to do what it claims, and even if yield() does cause a thread to step out of running and back to runnable, there's no guarantee the yielding thread won't just be chosen again over all the others! So while yield() might—and often does—make a running thread give up its slot to another runnable thread of the same priority, there's no guarantee.

    A yield() won't ever cause a thread to go to the waiting/sleeping/ blocking state. At most, a yield() will cause a thread to go from running to runnable, but again, it might have no effect at all.

    Source: SCJP Sun Certified Programmer book

    0 讨论(0)
  • 2020-11-27 03:22

    Yield adds the current thread to the ready queue and allows other threads to run. Sleep is not guaranteed to relinquish the cpu.

    0 讨论(0)
  • 2020-11-27 03:23

    It's platform-and-implementation-dependent, and they are likely not equivalent.

    The below snippet, when using Thread.sleep(0), most of the time gives the output:

    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    

    Whereas when using Thread.yield(), mostly gives:

    [0, 1, 1, 1, 1, 1, 1, 1, 1, 1]
    [0, 2, 2, 2, 2, 2, 2, 2, 2, 2]
    

    See snippet below:

    public class CompareSleepZeroAndYield {
        private ArrayList<Integer> list1 = new ArrayList<>();
        private ArrayList<Integer> list2 = new ArrayList<>();
    
        public ArrayList<Integer> getList1() {
            return list1;
        }
    
        public ArrayList<Integer> getList2() {
            return list2;
        }
    
        public CompareSleepZeroAndYield() {
            list1.add(0);
            list2.add(0);
        }
    
        public void tryFieldLock1() {
            synchronized (this.list1) {
                list1.add(list2.get(list2.size() - 1) + 1);
            }
        }
    
        public void tryFieldLock2() {
            synchronized (this.list2) {
                list2.add(list1.get(list1.size() - 1) + 1);
            }
        }
    
        public static void main(String[] args) {
            CompareSleepZeroAndYield obj = new CompareSleepZeroAndYield();
            Thread t1 = new Thread(new Runnable() {
                @Override
                public void run() {
                    int count = 10;
                    while (--count >0) {
                        obj.tryFieldLock1();
                        try {
                            Thread.sleep(0);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        // compare above and below
                        // Thread.yield()
                    }
                    System.out.println(obj.getList1());
                }
            });
            Thread t2 = new Thread(new Runnable() {
                @Override
                public void run() {
                    int count = 10;
                    while (--count >0) {
                        obj.tryFieldLock2();
    
                        try {
                            Thread.sleep(0);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        // compare above and below
                        // Thread.yield()
                    }
                    System.out.println(obj.getList2());
                }
            });
            t1.start();
            t2.start();
    }
    
    0 讨论(0)
  • 2020-11-27 03:24

    Thread.Sleep() has a slightly larger overhead because it creates a system that includes some kind of timer that will wake the process. (Depends on implementation basically)
    Bottom line it will call a Yield() in the end.

    Thread.Yield() Will just give-up the thread's turn, and gain it in the next round.

    Thread.Sleep(0) might have an optimization to just call yield. (Again, implementation)

    0 讨论(0)
提交回复
热议问题