java线程研究---(5)暂停Thread:yield

时间:2021-09-18 23:29:32

暂停Thread


yield方法:

  • 静态方法Thread.yield()
  • yield方法会让Thread对象直接从执行(running)状态进入等待执行(runnable)状态。
  • 这里的“直接”是指没有设置等待时间(没有blocked pool等待池的概念),也就是yield方法没有参数。
  • 但是!
  • 因为(running)状态和(runnable)状态之间的转换,需要cpu调度的:可能延迟一点时间,也可能一点也不延迟。
  • 所以我对yield的总结是:
    • 当一个Thread对象,调用Thread.yield()方法,
    • 其实是通知cpu开始调度:running--->runnable
    • 至于cpu何时开始调度,不得而知:可能延迟一点时间调度,也可能一点也不延迟调度。
    • 当cpu调度成功,当前Thread对象进入runnable状态。
    • 此时,可能由于没有其他的Thread对象抢占cpu,当前Thread对象会又被cpu调度,到running状态!

线程状态图没有更新。其实就是unning<--->runnable这个状态之间直接转换。


来看看一段代码吧。

Hello1
package thread;

public class Hello1 extends Thread {

	String name;

	public Hello1(String n) {
		this.name = n;
	}

	@Override
	public void run() {
                // 循环变成1000次
		for (int i = 1; i <= 1000; i++) {
			System.out.println(name + " Hello " + i);
		}
	}

}


Hello2
package thread;

public class Hello2 implements Runnable {

	String name;

	public Hello2(String n) {
		this.name = n;
	}

	@Override
	public void run() {
                // 循环变成1000次
		for (int i = 1; i <= 1000; i++) {
			System.out.println(name + " Hello " + i);
                        // 这里开始调用yield
			Thread.yield();
		}
	}

}

线程执行类
ThreadsExample1

package thread;

public class ThreadsExample1 {
	public static void main(String[] abc) throws InterruptedException {
		// thread task
		Hello1 h1 = new Hello1("Hello1:");
		Hello2 h2 = new Hello2("hello2:");

		// thread new , runnable
		Thread t1 = new Thread(h1, "thread1, hello1");
		Thread t2 = new Thread(h2, "thread2, hello2");

		t2.start();  // 注意这里,先开始t2线程
		t1.start();
	}
}


  • Hello1和Hello2的循环次数变长到1000
  • t2线程先启动。
  • 我们来看看打印结果


............................
hello2: Hello 372
hello2: Hello 373
hello2: Hello 374
hello2: Hello 375
Hello1: Hello 1
Hello1: Hello 2
Hello1: Hello 3
Hello1: Hello 4
............................
Hello1: Hello 997
Hello1: Hello 998
Hello1: Hello 999
Hello1: Hello 1000
hello2: Hello 376
hello2: Hello 377
hello2: Hello 378
hello2: Hello 379
hello2: Hello 380
hello2: Hello 381


  • 就如上打印结果来看。
  • t2 调用Thread.yield();之后,通知了cpu开始调度。
  • 但是cpu调度响应需要一点时间,就这一点时间内,t2还在运行,
  • 打印到hello2: Hello 375的时候,t2进入runnable状态, t1进入running状态。
  • t1打印到Hello1: Hello 1000的时候,t1进入死亡状态。
  • cpu调度t2继续执行,直至t2进入死亡状态。