1. 1. Thread.sleep()
api:
1 | public static native void sleep(long millis) throws InterruptedException; |
- 可以再任意地方执行
- 必须指定休眠时间
- 只能到时间自己醒过来
- 醒来后一定继续执行后续代码
- 需要捕获 InterruptedException 异常
- 不会释放持有的锁
- 休眠时线程装为 TIMED_WAITING
2. 2. Object.wait()
api:
1 | public final void wait() throws InterruptedException; |
- 必须在在 synchronized 中执行
- 可传入时长控制等待时长; 也可不传时长, 无限休眠直到有人唤醒
- 可以通过 notify() 唤醒, 但 notify() 必须在 wait() 之后执行, 否则会丢失唤醒信号
- 醒来后不一定立即执行后续代码
- 需要捕获 InterruptedException 异常
- 会释放持有的锁
- 休眠时线程装为 WAITING
3. 3. LockSupport.park()
api:
1 | public static void park(Object blocker); |
- 通过二元信号量实现的阻塞: 类似开关, 要么阻塞, 要么非阻塞
- 可以再任意地方执行
- 可传入时长控制等待时长; 也可不传时长, 无限休眠直到有人唤醒
- 可以通过 unpark() 唤醒, unpark() 方法可以比 park() 先执行, 也不会丢失唤醒信号
- 醒来后一定继续执行后续代码
- 无须捕获 InterruptedException 异常, 但是也会响应中断
- 不会释放持有的锁
- 休眠时线程装为 WAITING
4. 4. Condition.await()
api:
1 | void await() throws InterruptedException; |
- 必须在 ReentrantLock.lock() 块中执行
- 可传入时长控制等待时长; 也可不传时长, 无限休眠直到有人唤醒
- 会释放持有的锁
- 可以通过 signal() 唤醒, 但 signal() 必须在 await() 之后执行, 否则会丢失唤醒信号
- 醒来后不一定立即执行后续代码
- 需要捕获 InterruptedException 异常
- 底层盗用 LockSupport.part() 实现阻塞