2024-08-04
版权声明:本文为博主付费文章,严禁任何形式的转载和摘抄,维权必究。 本文链接:https://www.skjava.com/mianshi/baodian/detail/3478704586

回答

yield() 是 Thread 中的一个静态方法,它的作用是让当前正在执行的线程主动让出 CPU 使用权,但并不将线程从可运行状态(Runnable)变为阻塞状态(Blocked),也不放弃锁。换句话说,调用 yield() 的线程仍然是可运行的(Runnable),它只是告诉线程调度器,当前线程愿意让出 CPU 时间片,供其他同样处于可运行状态的线程使用。

扩展

通常情况下,yield() 的使用场景比较少,使用它时我们需要注意两个问题:

  1. 不可预测性yield() 仅仅只是让出 CPU 时间片,使用它理论上可以增加线程切换的机会,但是也只是理论上的可能,因为线程调度器并不会立刻进行切换,而且它可能会忽略这个提示,继续执行当前线程。
  2. 优先级的影响:高优先级的线程调用 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