# 1.基本使用

  • 暂停当前线程-LockSupport.park();
  • 恢复某个线程的运行- LockSupport.unpark(暂停线程对象) 这里注意一下,调用park方法,它的线程状态还是wait状态,可以理解成就是无限制的等待。将来调用unpark方法在变成可运行状态。

# 2.特点

与 Object 的 wait & notify 相比

  • wait,notify 和 notifyAll 必须配合 Object Monitor 一起使用,而 park,unpark不必
  • park & unpark 是以线程为单位来【阻塞】和【唤醒】线程,而 notify 只能随机唤醒一个等待线程,notifyAll 是唤醒所有等待线程,就不那么【精确】
  • park & unpark 可以先 unpark,而 wait & notify 不能先 notify

# 3.原理

每个线程都有自己的一个 Parker 对象,由三部分组成 _counter(容量) , _cond(存储阻塞队列) 和 _mutex(互斥锁)打个比喻 这里发现了一个比较好的例子给大家分享一下

image.png

  • park方法具体执行流程

image.png 调用park方法,首先会先判_counter方法的值如果等于0,就代表线程需要阻塞,然后获得互斥锁,线程进入_cond阻塞,然后再设置一次_counter=0

  • unpark方法执行流程

image.png 调用unpack方法,将_counter设置为1,唤醒 _cond 条件变量中的 Thread_0,将Thread0运行,然后设置counter为0;

  • 如果先调用unpack后再调用park方法

image.png 调用unpack方法会将_counter设置为1,当park方法执行时,发现等于1,就不需要进入阻塞,继续运行就可以了。