美文网首页
我猜你没有用过yield方法

我猜你没有用过yield方法

作者: 阿福德 | 来源:发表于2019-04-10 19:38 被阅读0次

    java.lang.Thread类中有很多的方法,比如start,join,sleep, interrupt等, 今天我们来谈谈yield方法, 这个是一个native方法, 如下:

    public static native void yield();
    

    这个方法的作用是出让自己的CPU, 让其他的线程有限执行,下面我们写一个类测试一下:

    import java.util.concurrent.BrokenBarrierException;
    import java.util.concurrent.CyclicBarrier;
    
    public class TestYield {
        public void test() throws InterruptedException {
            /**
             * 使用cyclicBarrier, 让两个线程同时执行。
             */
            CyclicBarrier cyclicBarrier = new CyclicBarrier(2);
            Thread a  = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        cyclicBarrier.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } catch (BrokenBarrierException e) {
                        e.printStackTrace();
                    }
                    //出让自己的CPU
                    Thread.yield();
                    for(int i=0;i<10;i++){
                        System.out.println("A"+i);
                    }
                }
            });
            Thread b  = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        cyclicBarrier.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } catch (BrokenBarrierException e) {
                        e.printStackTrace();
                    }
                    for(int i=0;i<30;i++){
                        System.out.println("B"+i);
                    }
                }
            });
            a.start();
            b.start();
            a.join();
            b.join();
        }
    
        public static void main(String[] args) throws InterruptedException {
            TestYield ty = new TestYield();
            ty.test();
        }
    }
    

    结果:

    B0
    B1
    B2
    B3
    B4
    B5
    A0
    A1
    A2
    A3
    A4
    A5
    A6
    A7
    A8
    A9
    B6
    B7
    B8
    B9
    B10
    B11
    B12
    B13
    B14
    B15
    B16
    B17
    B18
    B19
    B20
    B21
    B22
    B23
    B24
    B25
    B26
    B27
    B28
    B29
    Process finished with exit code 0

    每次执行的结果都不一样, 但大部分的结果都是B线程成执行完了, A线程还没有执行完, 虽然B线程的工作量更大。当然想上面的这种结果也经常出现。

    敲黑板划重点

    yield方法的作用就是出让自己当前的CPU,但是出让后,可能系统又将时间片再次分给了这个线程。
    有些同学说yield方法与join方法作用相反, 我觉得这种说法真是害人不浅。

    这样我们就有个疑问,既然是这结果又可能是A先执行完, 也可能是B线程先执行完。哪yield到底有什么用呢?

       /**
         * A hint to the scheduler that the current thread is willing to yield
         * its current use of a processor. The scheduler is free to ignore this
         * hint.
         *
         * <p> Yield is a heuristic attempt to improve relative progression
         * between threads that would otherwise over-utilise a CPU. Its use
         * should be combined with detailed profiling and benchmarking to
         * ensure that it actually has the desired effect.
         *
         * <p> 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.
         */
        public static native void yield();
    

    在自行看一下这个方法的javadoc, 最后一段说的很明白了。

    基本上你很少能用到这个方法, 这个方法可能对debug或者测试有用,可能可以帮助用来重现bug, 也可能在设计并发控制程序中有用。

    相关文章

      网友评论

          本文标题:我猜你没有用过yield方法

          本文链接:https://www.haomeiwen.com/subject/ljioiqtx.html