1. 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.
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.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 java.util.concurrent.locks package.
大概意思是说这个方法向调度程序发出一个暗示,暗示当前线程愿意放弃当前线程的CPU执行权。但是调度程序可以随意忽略这个提示,它并不能保证严格放弃当前线程执行权。在测试并发场景中可能有用,生产环境没有多大用处。
1.1 yield() 作用
- 线程让步:暂停当前正在执行的线程,把执行机会让给线程优先级相同或者更高的线程
- 若队列中没有同优先级或比当前线程优先级更高的线程则忽略此方法
那么了解了yield方法的作用,我们做一个例子来实现它
2 测试
2.1 无优先级测试
测试代码:
@Test
public void testYield() {
Thread thread1 = new Thread(() -> {
for (int i = 0; i < 10000; i++) {
if (i % 1000 == 0) {
System.out.println(Thread.currentThread().getName()+ "//" + i);
Thread.yield();
}
}
}, "Thread1");
Thread thread2 = new Thread(() -> {
for (int i = 0; i < 10000; i++) {
if (i % 1000 == 0) {
System.out.println(Thread.currentThread().getName()+ "//" + i);
Thread.yield();
}
}
}, "Thread2");
thread1.start();
thread2.start();
}
执行结果:
Thread2//0
Thread1//0
Thread2//1000
Thread1//1000
Thread1//2000
Thread2//2000
Thread1//3000
Thread2//3000
Thread1//4000
Thread2//4000
Thread1//5000
Thread1//6000
Thread2//5000
Thread1//7000
Thread1//8000
Thread2//6000
Thread1//9000
Thread2//7000
Thread2//8000
Thread2//9000
2.2 优先级测试
测试代码:
java
@Test
public void testYield() {
Thread thread1 = new Thread(() -> {
for (int i = 0; i < 10000; i++) {
if (i % 1000 == 0) {
System.out.println(Thread.currentThread().getName()+ "//" + i);
Thread.yield();
}
}
}, "Thread1");
Thread thread2 = new Thread(() -> {
for (int i = 0; i < 10000; i++) {
if (i % 1000 == 0) {
System.out.println(Thread.currentThread().getName()+ "//" + i);
Thread.yield();
}
}
}, "Thread2");
thread1.setPriority(Thread.MIN_PRIORITY);
thread2.setPriority(Thread.MAX_PRIORITY);
System.out.println(thread1.getPriority());
System.out.println(thread2.getPriority());
thread1.start();
thread2.start();
}
运行结果:
1
10
Thread1//0
Thread2//0
Thread1//1000
Thread2//1000
Thread1//2000
Thread2//2000
Thread1//3000
Thread2//3000
Thread1//4000
Thread2//4000
Thread1//5000
Thread2//5000
Thread1//6000
Thread2//6000
Thread1//7000
Thread2//7000
Thread1//8000
Thread2//8000
Thread1//9000
Thread2//9000
结论
可见yield方法并不是将CPU执行权交给优先级更高的线程,全看调度程序的心情。