6. LockSupport

回顾前面部分的源码分析,当需要阻塞或唤醒一个线程的时候,都会使用LockSupport工具来完成相应工作。LockSupport定义了一组公共静态方法,这些方法提供了最基本的线程阻塞和唤醒公共,而LockSupport也成为构建同步组件的基础工具。

LockSupport定义了一组以park开头的方法用来阻塞当前线程,以及upark方法用来唤醒线程。这些方法如下所示:

方法名称 描述
void park() 阻塞当前线程,如果调用unpark(Thread)或者当前线程被中断,才能从park()方法返回
void parkNanos(long nanos) 阻塞当前线程,最长不超过nanos纳秒,返回条件在park()的基础上增加了超时返回
void parkUntil(long deadline) 阻塞当前线程,直到deadline
void unpark(Thread thread) 唤醒处于阻塞的线程thread

在Java 6新增了void park(Object blocker), void parkNanos(Object blocker, long nanos), void parkUntil(Object blocker, long deadline)三个方法,用以实现阻塞当前线程的功能,其中参数blocker是用来标识当前线程在在等待的对象(以下称阻塞对象),该对象主要用于问题排查和系统监控。

下面的示例中,将对比parkNanos(long nanos)parkNanos(Object blocker, long nanos)方法来展示阻塞对象blocker的用处,代码片段和线程dump如下:

对比项\方法 parkNanos(long nanos) parkNanos(Object blocker, long nanos)
代码片段 LockSupport.parkNanos(TimeUnit.
SECONDS.toNanos(10))
LockSupport.parkNanos(test, TimeUnit.SECONDS.toNanos(10));
线程
dump
结果
"main" #1 prio=5 os_prio=0 tid=
0x0000025636fb9000 nid=0x1494 waiting
on condition [0x000000bbe3fff000]
java.lang.Thread.State:
TIMED_WAITING (parking)
at jdk.internal.misc.Unsafe.park
(java.base@10.0.2/Native Method)
at java.util.concurrent.locks.LockSupport.
parkNanos(java.base@10.0.2/
LockSupport.java:357)
"main" #1 prio=5 os_prio=0 tid=0x000002b0ceda8800 nid=0x724 waiting on condition [0x000000c6acafe000]
java.lang.Thread.State: TIMED_WAITING (parking)
at jdk.internal.misc.Unsafe.park(java.base
@10.0.2/Native Method)
- parking to wait for <0x00000006d119f9d8>
(a p5.LockSupportTest)

at java.util.concurrent.locks.LockSupport.parkNanos
(java.base@10.0.2/LockSupport.java:234)

从表中的线程dump结果可以看出,代码片段的内容是阻塞当前线程10s,但从线程dump结果可以看出,有阻塞对象的parkNanos方法能够传递给开发人员更多的线程信息。这是由于java 5之前,在线程阻塞(使用synchronized关键字)在一个对象上时,通过线程dump能够查看到该线程的阻塞对象,方便问题定位,而在java 5推出的Lock等并发工具时却遗漏了这一点,致使线程dump时无法提供阻塞对象的信息。因此,在java 6中,LockSupport新增了上述三个含有阻塞对象的park方法。

如果遗忘了如果进行线程dump操作,这里再温习一下。
运行测试方法(不一定是"main")后,在终端输入jps命令:
10964
2740 Launcher
9224 Program
12956 LockSupportTest
14300 KotlinCompileDaemon
7740 Jps

从中找到测试类对应的线程id,此处是 12956,然后终端输入jstack 12956,即可输出线程dump信息,然后从中寻找到对应测试方法的信息,此处为"main" #1 prio=5 os_prio=0 tid=0x0000025636fb9000 nid=0x1494 .....

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 关于文章涉及到的jdk源码,这里把最新的jdk源码分享给大家----->jdk源码 前言 在上篇文章《Java并发...
    AndyJennifer阅读 6,033评论 0 5
  • 原创文章&经验总结&从校招到A厂一路阳光一路沧桑 详情请戳www.codercc.com 1. LockSuppo...
    你听___阅读 13,201评论 1 9
  • LockSupport,构建同步组件的基础工具,帮AQS完成相应线程的阻塞或者唤醒的工作。 LockSupport...
    miaoLoveCode阅读 15,485评论 3 23
  • jstack用于打印出给定的java进程ID或core file或远程调试服务的Java堆栈信息,如果是在64位机...
    sherlock_6981阅读 4,666评论 0 0
  • 金庸走了,让我们懂得活着得有追求,只有奋斗终生才能有快意恩仇, 李咏走了,让我们知道生命必须依托健康,健康才是生命...
    言轻严青阅读 1,076评论 0 2

友情链接更多精彩内容