park/unpark是LockSurpport类中的方法,其基本使用为:
//暂停当前线程
LockSupport.park();
//恢复某个线程的运行
/LockSupport.unpark(暂停线程对象);
每个线程都有自己的一个parker对象,这个parker对象由_counter,_cond(条件变量),_mutex三部分组成。
举个例子:
一个线程就像一台小时候路边杂货店门口需要投币的游戏机,不过这台游戏机比较特殊,无论投多少个游戏币进去只算投进去一个,并且没有游戏币后会马上关机。parker就像这台游戏机的币池,_counter就像币池中的剩余币数(0为耗尽,1为还有余币),_cond就好比币池里控制游戏机电源开关的闸门。
调用park()就是看还有没有余币:
→如果没有余币,那么游戏机将断电,变成关机状态。
→如果还有余币,那么游戏机不需要关机,继续运行。
调用unpark()就像投币:
→如果游戏机是关机状态,就唤醒开机运行。
→如果游戏机正在运行,那么将补充一枚游戏币,将剩余币数+1,但多次调用unpark()也只能补充1枚游戏币。
具体例子:
1、
(1)当前线程调用Unsafe.park()方法
(2)检查_counter,发现_counter为0,此时获得_mutex互斥锁
(3)Thread-0进入_cond条件变量阻塞
(4)设置_count = 0
2、
(1)调用Unsafe.unpark(Thread_0)方法,设置_counter为1
(2)唤醒Thread-0
(3)Thread-0恢复运行
(4)重新设置_counter为0
3、
(1)调用Unsafe.unpark(Thread_0)方法,设置_counter为1
(2)当前线程调用Unsafe.park()方法
(3)检查_counter的值发现为1,Thread-0无需阻塞,继续运行
(4)将_counter置为0