park、Unpark

1.基本使用:

它们是LockSupport类中的方法

LockSupport.park(); //暂停当前线程

LockSupport.unpark(暂停线程对象); //恢复某个线程的运行

注意:

unpark可以在一个线程调用park方法之前使用,等该线程调用park方法后会立即恢复运行

与wait和notify比较
  1. 1.wait,notifynotifyAll 必须配合Object Monitor一起使用(即先获取到对象锁),而unpark不用
  2. 2.parkunpark是以线程为单位来阻塞和唤醒线程,而notify只能随机唤醒一个等待的线程
  3. 3.parkunpark可以先unpark,但是waitnotify不能先notify

原理:

每个线程都有自己的一个Parker对象(底层有C实现),由三部分组成 _counter _cond _nutex

线程就像一个旅行者,Parker就像它随身携带的背包,条件变量就像背包中的帐篷,_counter就像背包中的备用粮食(0为耗尽,1为充足)

调用park就是要看是否需要休息

  1. 如果备用粮食充足则不需要休息
  2. 如果备用粮食耗尽就需要休息

调用unpark就好比让备用粮食处于充足状态

  1. 如果此时线程在休息,就唤醒它
  2. 如果此时线程正在运行,那么它下次调用park方法,仅消耗掉备用粮食,不需要休息
  3. 因为背包空间有限,多次调用unpark仅仅会补充一份备用粮食<br />![1646898990954.png](https://cdn.nlark.com/yuque/0/2022/png/26737039/1647331819670-bcb401e7-40e9-42db-a917-35c159694434.png#clientId=u34df1b8e-1308-4&crop=0&crop=0&crop=1&crop=1&from=ui&id=uf56440ee&margin=%5Bobject%20Object%5D&name=1646898990954.png&originHeight=446&originWidth=783&originalType=binary&ratio=1&rotation=0&showTitle=false&size=152471&status=done&style=none&taskId=u9fcbac52-f2c2-4682-b56d-8a56ca813c5&title=)