Java线程暂停、等待、唤醒、让步总结

2020-11-15  本文已影响0人  AArman

Thread.sleep(long millis) : 使当前线程暂停指定时间,暂停期间该线程不参与CPU竞争;

@FastNative
private static native void sleep(Object lock, long millis, int nanos)
  throws InterruptedException;
  1. 不会释放占有的锁。
  2. 必须传入时间,到时会自动唤醒(无法主动唤醒,醒后继续执行后续代码)。
  3. Thread.sleep(0);//传入的时间为 【0】 或 【线程到时唤醒】,都会触发操作系统重新进行CPU竞争,竞争后也许是当前线程获得CPU控制权,也许是其他线程(和线程优先级有一定关系)。

Thread.yield();//线程让步

public static native void yield();
  1. 不会释放占有的锁。
  2. 使当前线程从运行状态转到可运行状态,而不是等待或阻塞状态。
  3. 使当前线程放弃执行的机会,让给其他线程执行(优先级高的只是概率大,也不一定必然就执行)。当前线程让出CPU权限后,CPU竞争后也有可能被再次执行。

Object.wait()(thread.wait(1000); thread.notify();调用的就是Object的方法)

@FastNative
public final native void wait() throws InterruptedException;

@FastNative
public final native void wait(long millis, int nanos) throws InterruptedException;

@FastNative
public final native void notify();
  1. 会释放占有的锁(调用后线程进入WAITING状态),时间可传可不传,不传表示一直阻塞下去;
  2. 不带时间的方法,需要另一个线程使用 Object.notify() 才能唤醒;
  3. 带时间的,假如没有被notify,到时会自动唤醒,这时又分好两种情况,一是立即获取到了锁,线程自然会继续执行;二是没有立即获取锁,线程进入同步队列等待获取锁;
  4. 如果在wait()之前执行了notify()会抛出 IllegalMonitorStateException 异常;

对线程的等待和唤醒,推荐使用如下方法:
//如果在park()之前执行了unpark()会怎样?线程不会被阻塞,直接跳过park(),继续执行后续内容;
LockSupport.park(Object blocker);//parkNanos(long nanos)//阻塞,等待,挂起
LockSupport.unpark(thread)

  1. 不会释放锁资源,不需要捕获中断异常
  2. 底层是调用的Unsafe的native方法;
  3. 可以被另一个线程调用LockSupport.unpark()方法唤醒;
  4. 不带超时的,需要另一个线程执行unpark()来唤醒,一定会继续执行后续内容;
上一篇 下一篇

猜你喜欢

热点阅读