join、sleep、wait、yield
方法名 | 所属类 | 是否释放锁 | 线程状态变化 | 用途 | 抛异常 |
---|---|---|---|---|---|
join() |
Thread 类 | ❌ 不释放锁 | 当前线程等待目标线程执行完 | 等待其他线程执行完再继续执行 | 是 |
sleep() |
Thread 类 | ❌ 不释放锁 | 当前线程暂停指定时间 | 模拟延时、节省 CPU 资源等 | 是 |
wait() |
Object 类 | ✅ 释放锁 | 当前线程等待被唤醒(notify) | 多线程通信、同步协作 | 是 |
yield() |
Thread 类 | ❌ 不释放锁 | 当前线程让出 CPU 资源 | 提示调度器可以切换线程 | 否 |
join() —— 等待其它线程执行完毕
Thread t = new Thread(() -> {...});
t.start();
t.join(); // 当前线程会等 t 线程执行完再继续
作用:让当前线程等待目标线程执行完再继续执行。
常用场景:主线程等待子线程处理完数据后再合并结果。
sleep() —— 当前线程休眠
Thread.sleep(1000); // 当前线程暂停 1 秒
不释放锁,不会进入阻塞队列。
用于模拟耗时、节流、轮询等场景。
wait() —— 等待并释放锁(需要和 notify() 搭配)
synchronized(obj) {
obj.wait(); // 当前线程释放 obj 锁并进入等待队列
}
必须放在 synchronized 块中使用。
会释放当前对象的锁,进入该对象的等待队列。
与 notify() / notifyAll() 搭配使用,实现线程协作。
wait也可以传入唤醒时间,obj.wait(3000),表示3秒之后自动唤醒,重新开始竞争锁。
它不是主动去抢锁,而是被 JVM 内部唤醒,然后参与锁的等待队列,之后由 JVM 安排锁竞争和 CPU 调度。
所以 先参与锁竞争,再等待 CPU 调度执行;
如果锁还没拿到,线程处于 BLOCKED,即:准备好了但排队中;
拿到锁后,线程才从 wait() 后继续执行代码
yield() —— 礼让(非强制性)
Thread.yield();
当前线程让出 CPU,调度器可能会选择其他线程执行。
不释放锁,可能什么也不发生(平台相关行为)。
一般用于线程调度优化,控制 CPU 分配顺序。