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

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()来唤醒,一定会继续执行后续内容;
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容