0%

线程休眠的方式

1. 1. Thread.sleep()

api:

1
public static native void sleep(long millis) throws InterruptedException;
  • 可以再任意地方执行
  • 必须指定休眠时间
  • 只能到时间自己醒过来
  • 醒来后一定继续执行后续代码
  • 需要捕获 InterruptedException 异常
  • 不会释放持有的锁
  • 休眠时线程装为 TIMED_WAITING

2. 2. Object.wait()

api:

1
2
3
public final void wait() throws InterruptedException;
public final void wait(long timeoutMillis, int nanos) throws InterruptedException;
public final native void wait(long timeoutMillis) throws InterruptedException;
  • 必须在在 synchronized 中执行
  • 可传入时长控制等待时长; 也可不传时长, 无限休眠直到有人唤醒
  • 可以通过 notify() 唤醒, 但 notify() 必须在 wait() 之后执行, 否则会丢失唤醒信号
  • 醒来后不一定立即执行后续代码
  • 需要捕获 InterruptedException 异常
  • 会释放持有的锁
  • 休眠时线程装为 WAITING

3. 3. LockSupport.park()

api:

1
2
3
public static void park(Object blocker);
public static void parkNanos(Object blocker, long nanos);
public static void parkUntil(Object blocker, long deadline);
  • 通过二元信号量实现的阻塞: 类似开关, 要么阻塞, 要么非阻塞
  • 可以再任意地方执行
  • 可传入时长控制等待时长; 也可不传时长, 无限休眠直到有人唤醒
  • 可以通过 unpark() 唤醒, unpark() 方法可以比 park() 先执行, 也不会丢失唤醒信号
  • 醒来后一定继续执行后续代码
  • 无须捕获 InterruptedException 异常, 但是也会响应中断
  • 不会释放持有的锁
  • 休眠时线程装为 WAITING

4. 4. Condition.await()

api:

1
2
3
4
void await() throws InterruptedException;
boolean await(long time, TimeUnit unit) throws InterruptedException;
long awaitNanos(long nanosTimeout) throws InterruptedException;
boolean awaitUntil(Date deadline) throws InterruptedException;
  • 必须在 ReentrantLock.lock() 块中执行
  • 可传入时长控制等待时长; 也可不传时长, 无限休眠直到有人唤醒
  • 会释放持有的锁
  • 可以通过 signal() 唤醒, 但 signal() 必须在 await() 之后执行, 否则会丢失唤醒信号
  • 醒来后不一定立即执行后续代码
  • 需要捕获 InterruptedException 异常
  • 底层盗用 LockSupport.part() 实现阻塞