回答
yield()
是 Thread 中的一个静态方法,它的作用是让当前正在执行的线程主动让出 CPU 使用权,但并不将线程从可运行状态(Runnable)变为阻塞状态(Blocked),也不放弃锁。换句话说,调用 yield()
的线程仍然是可运行的(Runnable),它只是告诉线程调度器,当前线程愿意让出 CPU 时间片,供其他同样处于可运行状态的线程使用。
扩展
通常情况下,yield()
的使用场景比较少,使用它时我们需要注意两个问题:
- 不可预测性:
yield()
仅仅只是让出 CPU 时间片,使用它理论上可以增加线程切换的机会,但是也只是理论上的可能,因为线程调度器并不会立刻进行切换,而且它可能会忽略这个提示,继续执行当前线程。 - 优先级的影响:高优先级的线程调用
yield()
后,大概率仍会被线程调度器再次执行,而低优先级的线程调用yield()
后,则更有可能让出 CPU 给其他同优先级或更高优先级的线程。
当一个线程调用 yield()
方法时,线程调度器会根据内部的调度策略决定下一个要执行的线程。所以,yield()
的调用只是一个提示,它依赖于线程调度器的实现,在不同的平台和 JVM 实现中可能表现不同。下面是一个简单的实例:
public class YieldExample {
public static void main(String[] args) {
Runnable runnable = () -> {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + " - " + i);
Thread.yield();
}
};
Thread thread1 = new Thread(runnable, "Thread-1");
Thread thread2 = new Thread(runnable, "Thread-2");
thread1.start();
thread2.start();
}
}
理论上来说,应该是 Thread-1 和 Thread-2 交替执行,但是 yield()
要依赖具体的线程调度策略,所以执行结果会多变:
结果一:
Thread 1 - 0
Thread 1 - 1
Thread 1 - 2
Thread 2 - 0
Thread 2 - 1
Thread 2 - 2
Thread 2 - 3
Thread 1 - 3
Thread 2 - 4
Thread 1 - 4
结果二:
Thread 1 - 0
Thread 2 - 0
Thread 1 - 1
Thread 2 - 1
Thread 1 - 2
Thread 2 - 2
Thread 1 - 3
Thread 1 - 4
Thread 2 - 3
Thread 2 - 4