Java中thread.yield()方法的使用

Java中thread.yield()方法的使用

​ Java线程开启是使用star()方法,启动线程,让线程变成就绪状态等待 CPU 调度后执行。而thread.yield()方法则是使当前线程由执行状态,变成为就绪状态,让出cpu时间,在下一个线程执行时候,此线程有可能被执行,也有可能没有被执行。我们做一个测试的例子

一、YieldTest.java代码

class ThreadA extends Thread{
    public ThreadA(String name){
        super(name);
    }
    public void run(){
        for(int i=0; i <10; i++){
            System.out.printf("%s [%d]:%d
", this.getName(), this.getPriority(), i);
            // i整除9时,调用yield
            if (i % 9 == 0)
                Thread.yield();
        }
    }
}
public class YieldTest{
    public static void main(String[] args){
        ThreadA t1 = new ThreadA("t1");
        ThreadA t2 = new ThreadA("t2");
        t1.start();
        t2.start();
    }
}

运行结果:

t2 [5]:0
t1 [5]:0
t2 [5]:1
t2 [5]:2
t2 [5]:3
t2 [5]:4
t2 [5]:5
t2 [5]:6
t2 [5]:7
t2 [5]:8
t2 [5]:9
t1 [5]:1
t1 [5]:2
t1 [5]:3
t1 [5]:4
t1 [5]:5
t1 [5]:6
t1 [5]:7
t1 [5]:8
t1 [5]:9

我们可以看到首先运行的的是t2 [5]:0。如果改为整除5的话,在运行至输出t1 [5]:5的时候也没有转到其他。yield()虽然可以让线程由“运行状态”进入到“就绪状态”;但是,它不一定会让其它线程获取CPU执行权(即,其它线程进入到“运行状态”),即使这个“其它线程”与当前调用yield()的线程具有相同的优先级。

二、YieldTest2.Java代码

public class YieldTest2 extends Thread{
    YieldTest2(String name){
        super(name);
    }

    @Override
    public void run() {
        for (int i = 0; i < 50; i++) {
            System.out.println("" + this.getName() + "-----" + i);
            // 当i为30时,该线程就会把CPU时间让掉,让其他或者自己的线程执行(也就是谁先抢到谁执行)
            if (i == 30) {
                this.yield();
            }
        }
    }
    public static void main(String[] args) {
        YieldTest2 yt1 = new YieldTest2("张三");
        YieldTest2 yt2 = new YieldTest2("李四");
        yt1.start();
        yt2.start();
    }
}

此时运行结果,截取片段:

张三-----0
张三-----1
张三-----2
张三-----3
张三-----4
张三-----5
张三-----6
张三-----7
张三-----8
张三-----9
张三-----10
张三-----11
张三-----12
张三-----13
张三-----14
张三-----15
张三-----16
张三-----17
张三-----18
张三-----19
张三-----20
张三-----21
张三-----22
李四-----0
李四-----1
李四-----2
张三-----23
张三-----24
张三-----25
张三-----26
张三-----27
张三-----28
张三-----29
李四-----3
李四-----4
李四-----5
李四-----6
李四-----7
李四-----8
李四-----9

我们首先看到张三运行到22的时候,李四线程开始运行了,然后继续张三运行,当运行至张三29的时候。李四抢占了CPU。此时李四开始跑。

多运行几次结果会有不同的情况,会出现张三跑到29时。张三抢占了CPU,继续跑30。

张三-----0
李四-----0
张三-----1
李四-----1
张三-----2
李四-----2
张三-----3
李四-----3
张三-----4
李四-----4
张三-----5
李四-----5
张三-----6
李四-----6
张三-----7
李四-----7
张三-----8
李四-----8
张三-----9
李四-----9
张三-----10
李四-----10
张三-----11
李四-----11
张三-----12
李四-----12
张三-----13
李四-----13
张三-----14
李四-----14
张三-----15
李四-----15
张三-----16
张三-----17
张三-----18
张三-----19
李四-----16
张三-----20
张三-----21
张三-----22
张三-----23
张三-----24
张三-----25
张三-----26
张三-----27
张三-----28
张三-----29
张三-----30
张三-----31
张三-----32
张三-----33
张三-----34
张三-----35
张三-----36

三、总结

  • 使当前线程从执行状态(运行状态)变为可执行态(就绪状态)。cpu会从众多的可执行态里选择,也就是说,当前也就是刚刚的那个线程还是有可能会被再次执行到的,并不是说一定会执行其他线程而该线程在下一次中不会执行到了。
  • 用了yield方法后,该线程就会把CPU时间让掉,让其他或者自己的线程执行(也就是谁先抢到谁执行)。
  • 通过yield方法来实现两个线程的交替执行。不过请注意:这种交替并不一定能得到保证。
  • 通过yield方法来实现两个线程的交替执行。不过请注意:这种交替并不一定能得到保证。
原文地址:https://www.cnblogs.com/hequnwang/p/13957913.html