我猜你没有用过yield方法

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, 也可能在设计并发控制程序中有用。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 该文章转自:http://blog.csdn.net/evankaka/article/details/44153...
    加来依蓝阅读 7,400评论 3 87
  • Java多线程学习 [-] 一扩展javalangThread类 二实现javalangRunnable接口 三T...
    影驰阅读 3,022评论 1 18
  • 本文主要讲了java中多线程的使用方法、线程同步、线程数据传递、线程状态及相应的一些线程函数用法、概述等。 首先讲...
    李欣阳阅读 2,527评论 1 15
  • 一、进程和线程 进程 进程就是一个执行中的程序实例,每个进程都有自己独立的一块内存空间,一个进程中可以有多个线程。...
    阿敏其人阅读 2,635评论 0 13
  • 65岁时,父亲已有过两年多的咽炎史,而且在那两年里,双目只能晃到模糊的影儿。 这次父亲的慢性咽炎复发,声音嘶哑,没...
    篱笆影阅读 957评论 4 1