我猜你没有用过yield方法

2019-04-10  本文已影响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, 也可能在设计并发控制程序中有用。

上一篇下一篇

猜你喜欢

热点阅读