【J.U.C】LockSupport
引言
LockSupport是用于创建锁和其他同步类的阻塞原语,通过调用Unsafe函数中的接口实现阻塞和解除阻塞的。
pack
方法 | 解释 |
---|---|
park(Object) | 挂起当前线程 |
parkNanos(Object, long) | 指定了一个挂起时间(相对于当前的时间),时间到后自动被唤醒;例如1000纳秒后自动唤醒 |
parkUntil(Object, long) | 指定一个挂起时间(绝对时间),时间到后自动被唤醒;例如2018-02-12 21点整自动被唤醒。 |
park() | 和park(Object)相比少了挂起前为线程设置blocker、被唤醒后清理blocker的操作。 |
parkNanos(long) | 和parkNanos(Object, long)类似,仅少了blocker相关的操作 |
parkUntil(long) | 和parkUntil(Object, long)类似,仅少了blocker相关的操作 |
park(Object blocker)源码分析:
1 | /** |
park支持blocker对象作为参数。此blocker对象在线程受阻塞时被记录,这样监视工具和诊断工具就可以确定线程受阻塞的原因。
unpark
唤醒调用 park 后阻塞的线程,参数为需要唤醒的线程。
unpark(Thread thread)源码:
1 | /** |
挂起与阻塞分析
对线程来说, LockSupport的park/unpark更符合阻塞和唤醒的语义,他们以“线程”作为方法的参数,语义更清晰,使用起来也更方便。而wait/notify使“线程”的阻塞/唤醒对线程本身来说是被动的,要准确的控制哪个线程、什么时候阻塞/唤醒是很困难的,所以是要么随机唤醒一个线程(notify)要么唤醒所有的(notifyAll)。
park和unpark方法不会出现Thread.suspend和Thread.resume的死锁问题。这是因为许可的存在,调用park的线程和另一个试图将其unpark的线程之间的将没有竞争关系。此外,如果线程被中断或者超时,则park将返回。
park方法还可以在其他任何时间“毫无理由”地返回,因此通常必须在重新检查返回条件的循环里调用此方法。从这个意义上说,park 是“忙碌等待”的一种优化,它不会浪费这么多的时间进行自旋,但是必须将它与unpark配对使用才更高效。
####使用例子
如图:
JDK中主要是JUC中使用,CAS和LockSupport是JUC的基石。disruptor框架也使用了LockSupport。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 ClawHub的技术分享!