线程调度(yield、join)

1. yield():线程的「谦让」

作用

  • 提示调度器 当前线程愿意让出CPU,但调度器可能会忽略此提示(不保证立即生效)。
  • 目的是 让相同优先级的其他线程有执行机会,避免一个线程长时间占用CPU。

特点

  • 不释放锁
  • 线程状态保持 RUNNABLE(不会进入阻塞状态)。
  • 适用场景:线程执行非关键任务时,主动让出资源。

示例代码

public class YieldExample {
    public static void main(String[] args) {
        Thread producer = new Thread(() -> {
            for (int i = 0; i < 5; i++) {
                System.out.println("Producer working...");
                Thread.yield(); // 主动让出CPU
            }
        });

        Thread consumer = new Thread(() -> {
            for (int i = 0; i < 5; i++) {
                System.out.println("Consumer working...");
            }
        });

        producer.start();
        consumer.start();
    }
}

输出可能(因线程调度顺序不确定):

Producer working...
Consumer working...
Consumer working...
Producer working...
...

2. join():线程的「合并」

作用

  • 当前线程等待目标线程终止 后再继续执行。
  • 本质是通过调用目标线程的 wait() 方法实现阻塞。

特点

  • 释放锁(因为底层调用wait())。
  • 适用场景:需要 线程顺序执行依赖其他线程结果 时。

示例代码

public class JoinExample {
    public static void main(String[] args) throws InterruptedException {
        Thread worker = new Thread(() -> {
            try {
                Thread.sleep(2000);
                System.out.println("Worker task done!");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        worker.start();
        System.out.println("Main thread waiting...");
        worker.join(); // 主线程等待worker线程结束
        System.out.println("Main thread continues.");
    }
}

输出(固定顺序):

Main thread waiting...
Worker task done!
Main thread continues.

3. 关键区别总结

特性 yield() join()
目的 让出CPU资源 等待其他线程结束
是否阻塞 否(线程仍为RUNNABLE) 是(当前线程进入WAITING状态)
锁行为 不释放锁 释放锁(因底层调用wait()
确定性 依赖调度器,不保证立即生效 严格保证目标线程执行完毕
典型场景 优化CPU密集型任务的公平性 线程间顺序执行或结果依赖
posted @ 2024-08-02 13:55  CyrusHuang  阅读(35)  评论(0)    收藏  举报