并发第七弹 LockSupport类

小伙伴们周末愉快!
今天要介绍的内容是Java中的LockSupport类,LockSupport是个工具类,但是不要小看它的作用,该工具类是创建锁和其它同步类的基础,LockSupport的作用是唤醒和阻塞线程
并发第六弹 AQS抽象队列同步器 中介绍了AQS,AQS中的线程等待队列的阻塞与唤醒就是通过LockSupport来完成的。

我们先来看一下LockSupport的API,如下图所示。
并发第七弹 LockSupport类

park()与unpark(Thread thread)

park()方法用于阻塞一个线程,而unpark(Thread thread)用于唤醒一个指定的线程。
LockSupport与每个使用它的线程关联一个许可证,如果调用park方法的线程已经拿到了与LockSupport关联的许可证,则调用Locksupport.park()会马上返回,否则阻塞。
而unpark(Thread thread)就是为指定的线程分配一个许可证。

接下来有一个疑问,park()方法阻塞线程的原理是什么呢?先来看一下park()方法的源码,如下图所示。
并发第七弹 LockSupport类

其实LockSupport.park()调用的是Unsafe类park()方法,而Unsafe类在我的关于CAS的那篇文章 并发第四弹 Java原子类中的CAS算法 中已经初步认识过了,看来Unsafe不仅提供了CAS操作方法,还提供了线程的阻塞与唤醒方法。Unsafe类的park与unpark方法源码如下。

并发第七弹 LockSupport类

可以看到,这两个都是本地方法,我们自然而然就想到,线程的阻塞与唤醒是依赖于操作系统

LockSupport.park()使线程阻塞时,该线程会被interrupt打断,但是不会抛出InterruptedException异常,且该线程的中断状态会改变,我们可以通过中断状态判断该线程是何种原因(获取到许可证或被打断)被唤醒的

需要注意的是:任何抛出了InterruptedException异常的方法都会将中断状态清零

其它API

park()和unpark(Thread thread)讲完了,我们再来看看LockSupport的其它的API。

park(Object blocker)与getBlocker(Thread t):
  • 在阻塞时会将blocker对象记录到线程内部,诊断工具(比如jstack pid)通过调用LockSupport.getBlocker(Thread t)方法获取blocker对象,从而知道线程在哪里被阻塞(为了知道线程在哪里被阻塞,通过将blocker对象设置为this);

parkNanos(long nanos):
  • 该线程阻塞指定时间后自动被唤醒,单位是纳秒;

parkUntil(long deadline):
  • 该线程阻塞到指定时刻后自动被唤醒;



由于LockSupport挺简单的,我就不写例子演示了。

原文始发于微信公众号(初心JAVA):并发第七弹 LockSupport类

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/35534.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!