java多线程中-用于同步控制的各种方法作用
java多线程中-用于同步控制的各种方法作用
1 wait()
/ notify()
/ notifyAll()
作用
wait()
让当前线程进入等待队列 ,同时释放锁 ,直到 notify()
或 notifyAll()
唤醒。
方法定义
void wait() // 让当前线程进入等待状态 void wait(long timeout) // 等待指定时间后超时返回 void wait(long timeout, int nanos) // 更精细的超时控制 void notify() // 唤醒在该对象监视器上等待的一个线程 void notifyAll() // 唤醒所有等待的线程
特点
- 必须在
synchronized
代码块或方法中调用,否则会抛出IllegalMonitorStateException
。 wait()
调用后释放锁 ,等待notify()
或notifyAll()
唤醒。notify()
只唤醒一个 等待的线程,notifyAll()
唤醒所有等待线程 。- 唤醒后线程需要重新竞争锁 ,才能继续执行。
示例
class WaitNotifyExample { private static final Object lock = new Object(); public static void main(String[] args) { Thread threadA = new Thread(() -> { synchronized (lock) { try { System.out.println(“线程 A:等待…”); lock.wait(); System.out.println(“线程 A:被唤醒,继续执行”); } catch (InterruptedException e) { e.printStackTrace(); } } }); Thread threadB = new Thread(() -> { synchronized (lock) { System.out.println(“线程 B:唤醒线程 A”); lock.notify(); } }); threadA.start(); try { Thread.sleep(1000); } catch (InterruptedException e) {} threadB.start(); } }
2 park()
/ unpark()
作用
park()
让线程进入阻塞状态 ,unpark()
唤醒线程。
方法定义
void LockSupport.park() // 挂起当前线程 void LockSupport.parkNanos(long nanos) // 挂起指定纳秒 void LockSupport.parkUntil(long deadline) // 挂起直到某个时间点 void LockSupport.unpark(Thread thread) // 唤醒指定的线程
特点
- 不依赖
synchronized
,可以直接调用。 - 不会释放锁 ,与
wait()
的行为不同。 unpark(thread)
可以先调用,再调用park()
也不会影响结果。park()
使用许可机制 ,每次unpark()
只给一个线程一个许可 。
示例
import java.util.concurrent.locks.LockSupport; class ParkUnparkExample { public static void main(String[] args) { Thread thread = new Thread(() -> { System.out.println(“线程 A:等待被唤醒…”); LockSupport.park(); System.out.println(“线程 A:被唤醒,继续执行”); }); thread.start(); try { Thread.sleep(1000); } catch (InterruptedException e) {} System.out.println(“主线程:唤醒线程 A”); LockSupport.unpark(thread); } }
3 interrupt()
作用
interrupt()
让线程从阻塞 或等待 状态中被打断,并抛出 InterruptedException
。
方法定义
void Thread.interrupt() // 中断线程 boolean Thread.isInterrupted() // 检测是否被中断 static boolean Thread.interrupted() // 检测当前线程是否被中断,并清除中断标志
特点
interrupt()
只是标记线程被中断 ,不会真正终止线程。- 如果线程正在
sleep()
、wait()
、park()
,会抛InterruptedException
并清除中断状态。 isInterrupted()
仅检查中断状态,不清除,interrupted()
既检查又清除 。
示例
class InterruptExample { public static void main(String[] args) { Thread thread = new Thread(() -> { while (!Thread.currentThread().isInterrupted()) { System.out.println(“线程 A 正在运行…”); try { Thread.sleep(1000); } catch (InterruptedException e) { System.out.println(“线程 A 被中断,退出循环”); break; } } }); thread.start(); try { Thread.sleep(3000); } catch (InterruptedException e) {} thread.interrupt(); } }
4 sleep()
作用
让线程休眠一段时间,不释放锁。
方法定义
void Thread.sleep(long millis) void Thread.sleep(long millis, int nanos)
特点
sleep()
不会释放锁 ,只是让线程暂停执行。sleep()
期间如果被interrupt()
调用,会抛InterruptedException
并立即返回。
示例
class SleepExample { public static void main(String[] args) { Thread thread = new Thread(() -> { try { System.out.println(“线程 A:休眠 2 秒…”); Thread.sleep(2000); System.out.println(“线程 A:休眠结束,继续执行”); } catch (InterruptedException e) { System.out.println(“线程 A 被中断”); } }); thread.start(); } }
5 yield()
作用
让当前线程主动让出 CPU 资源,进入就绪状态 。
方法定义
static void Thread.yield()
特点
yield()
不会释放锁 ,只是让出 CPU,仍然可能马上重新调度到该线程。yield()
只是一个提示 ,不保证会立即让出 CPU。
示例
class YieldExample { public static void main(String[] args) { Thread thread = new Thread(() -> { for (int i = 0; i < 5; i++) { System.out.println(“线程 A 运行:” + i); Thread.yield(); } }); thread.start(); } }
6 join()
作用
让当前线程等待另一个线程执行完毕 。
方法定义
void Thread.join() void Thread.join(long millis)
特点
join()
让调用线程等待目标线程执行完毕 。- 可以指定超时,避免无限等待。
示例
class JoinExample { public static void main(String[] args) { Thread thread = new Thread(() -> { System.out.println(“线程 A:执行任务…”); try { Thread.sleep(2000); } catch (InterruptedException e) {} System.out.println(“线程 A:任务完成”); }); thread.start(); try { thread.join(); } catch (InterruptedException e) {} System.out.println(“主线程:等待线程 A 结束后继续执行”); } }
7 线程同步方法对比
方法 | 释放锁 | 作用 | 唤醒方式 |
---|---|---|---|
wait() | ✅ | 进入等待队列 | notify() / notifyAll() |
park() | ❌ | 阻塞线程 | unpark(thread) |
sleep() | ❌ | 休眠线程 | 时间结束或 interrupt() |
interrupt() | ❌ | 中断线程 | 抛出 InterruptedException |
join() | ❌ | 等待另一个线程结束 | 目标线程执行完毕 |