Java Thread.yield详解

转自 https://blog.csdn.net/dabing69221/article/details/17426953

前言:
前几天复习了一下多线程,发现有许多网上讲的都很抽象,所以,自己把网上的一些案例总结了一下!

一、Thread.yield( )方法:

使当前线程从执行状态(运行状态)变为可执行态(就绪状态)。cpu会从众多的可执行态里选择,也就是说,当前也就是刚刚的那个线程还是有可能会被再次执行到的,并不是说一定会执行其他线程而该线程在下一次中不会执行到了。因此,使用yield()的目的是让具有相同优先级的线程之间能够适当的轮换执行。结论:大多数情况下,yield()将导致线程从运行状态转到可运行状态,但有可能没有效果。

Java线程中有一个Thread.yield( )方法,很多人翻译成线程让步。顾名思义,就是说当一个线程使用了这个方法之后,它就会把自己CPU执行的时间让掉,让自己或者其它的线程运行。

打个比方:现在有很多人在排队上厕所,好不容易轮到这个人上厕所了,突然这个人说:“我要和大家来个竞赛,看谁先抢到厕所!”,然后所有的人在同一起跑线冲向厕所,有可能是别人抢到了,也有可能他自己有抢到了。我们还知道线程有个优先级的问题,那么手里有优先权的这些人就一定能抢到厕所的位置吗? 不一定的,他们只是概率上大些,也有可能没特权的抢到了。

二、实例

例子1:

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

运行结果:
注意:测试环境为单核

  • 第一种情况:李四(线程)当执行到30时会CPU时间让掉,这时张三(线程)抢到CPU时间并执行。
    在这里插入图片描述
  • 第二种情况:李四(线程)当执行到30时会CPU时间让掉,这时李四(线程)抢到CPU时间并执行。
    在这里插入图片描述

本文来自 realnewdream 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/dabing69221/article/details/17426953?utm_source=copy

例子2:

转自 https://blog.csdn.net/hello_word2/article/details/52885398

public class yeld {
 
	public static void main(String[] args) {
		ThreadDemo demo = new ThreadDemo();
		Thread thread = new Thread(demo, "花花");
		Thread thread1 = new Thread(demo, "草草");
		thread.start();
		thread1.start();
	}
}
 
class ThreadDemo implements Runnable {
 
	@Override
	public void run() {
		for (int i = 0; i < 5; i++) {
			if (i == 3) {
				System.out.println("当前的线程是     " + Thread.currentThread().getName());
				Thread.currentThread().yield();
			}
			System.out.println("执行的是    " + Thread.currentThread().getName());
		}
 
	}
 
}

运行结果

    执行的是    草草
    执行的是    草草
    执行的是    草草
    当前的线程是     草草 //并没有礼让
    执行的是    草草
    执行的是    草草
    执行的是    花花
    执行的是    花花
    执行的是    花花
    当前的线程是     草草 //礼让啦
    执行的是    花花
    执行的是    花花

例子3:

转自 https://www.cnblogs.com/java-spring/p/8309931.html
更加真切的说明,优先级搞得线程不一定能抢到cpu。

public class YieldExcemple {

    public static void main(String[] args) {
        Thread threada = new ThreadA();
        Thread threadb = new ThreadB();
        // 设置优先级:MIN_PRIORITY最低优先级1;NORM_PRIORITY普通优先级5;MAX_PRIORITY最高优先级10
        threada.setPriority(Thread.MIN_PRIORITY);
        threadb.setPriority(Thread.MAX_PRIORITY);

        threada.start();
        threadb.start();
    }
}

class ThreadA extends Thread {
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println("ThreadA--" + i);
            Thread.yield();
        }
    }
}

class ThreadB extends Thread {
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println("ThreadB--" + i);
            Thread.yield();
        }
    }
}

本以为运行结果如下:

ThreadB--0
ThreadA--0
ThreadB--1
ThreadA--1
ThreadB--2
ThreadA--2
ThreadB--3
ThreadA--3
ThreadB--4
ThreadA--4
ThreadB--5
ThreadA--5
ThreadB--6
ThreadA--6
ThreadB--7
ThreadA--7
ThreadB--8
ThreadA--8
ThreadB--9
ThreadA--9

结果却出现了多种情况,如下:

ThreadB--0
ThreadB--1
ThreadB--2
ThreadB--3
ThreadB--4
ThreadB--5
ThreadB--6
ThreadB--7
ThreadB--8
ThreadB--9
ThreadA--0
ThreadA--1
ThreadA--2
ThreadA--3
ThreadA--4
ThreadA--5
ThreadA--6
ThreadA--7
ThreadA--8
ThreadA--9

或者

ThreadB--0
ThreadA--0
ThreadB--1
ThreadA--1
ThreadA--2
ThreadA--3
ThreadA--4
ThreadA--5
ThreadA--6
ThreadA--7
ThreadA--8
ThreadA--9
ThreadB--2
ThreadB--3
ThreadB--4
ThreadB--5
ThreadB--6
ThreadB--7
ThreadB--8
ThreadB--9

后翻阅资料得知:

Java线程中的Thread.yield( )方法,译为线程让步。顾名思义,就是说当一个线程使用了这个方法之后,它就会把自己CPU执行的时间让掉, 让自己或者其它的线程运行,注意是让自己或者其他线程运行,并不是单纯的让给其他线程。

yield()的作用是让步。它能让当前线程由“运行状态”进入到“就绪状态”,从而让其它具有相同优先级的等待线程获取执行权;但是,并不能保证在当前线程调用yield()之后,其它具有相同优先级的线程就一定能获得执行权;也有可能是当前线程又进入到“运行状态”继续运行!

举个例子:一帮朋友在排队上公交车,轮到Yield的时候,他突然说:我不想先上去了,咱们大家来竞赛上公交车。然后所有人就一块冲向公交车,有可能是其他人先上车了,也有可能是Yield先上车了。

但是线程是有优先级的,优先级越高的人,就一定能第一个上车吗?这是不一定的,优先级高的人仅仅只是第一个上车的概率大了一点而已,最终第一个上车的,也有可能是优先级最低的人。并且所谓的优先级执行,是在大量执行次数中才能体现出来的。

猜你喜欢

转载自blog.csdn.net/csdnlijingran/article/details/82974515