您的位置:首页 > 编程语言 > Java开发

java多线程解说【玖】_锁实现:LockSupport工具类

2018-02-23 16:31 627 查看
前面的文章介绍了几种锁的实现:

java多线程解说【肆】_锁实现:wait()/notify()

java多线程解说【伍】_锁实现:ReentrantLock的实现

java多线程解说【陆】_锁实现:Condition的实现

java多线程解说【捌】_锁实现:读写锁ReentrantReadWriterLock

本篇文章再介绍另一个LockSupport工具类。

LockSupport工具类

LockSupport提供了一组公共静态方法,提供了最基本的线程阻塞和唤醒功能,LockSupport也是构建同步组件的基础工具(AQS中大量方法使用)。

LockSupport定义了一组以park开头的方法来阻塞当前线程,以及unpark(Thread thread)方法来唤醒一个被阻塞的线程。

park()

阻塞当前线程,如果调用unpark(Thread thread)方法或当前线程被中断,才能重新获取调度

parkNanos(long nanos)

阻塞当前线程,最长不超过nanos纳秒,返回条件在park()上增加了超时时间

parkUntil(long deadline)

阻塞当前线程,直到deadline时间

unpark(Thread thread)

唤醒处于阻塞状态的线程

从JDK6开始,LockSupport在park开头的方法中增加了传入blocker参数,blocker就是用来标识当前线程咋等待的对象。因为在JDK5之前使用synchronized来实现线程阻塞的时候,为方便问题定位通过线程dump可以看到该线程的阻塞对象。而在JDK5中的LockSupport没有支持这一点导致排查问题时极大不便,因此在JDK6版本中补上了这三个接口:

park(Object blocker)

parkNanos(long nanos,Object blocker)

parkUntil(long deadline,Object blocker)

如何查看线程dump

在Java项目中,有很多时候需要做线程dump,比如,系统挂起、死锁、不能创建更多本地线程的OOME、CPU消耗过多等等;甚至有些堆内存溢出也可能跟线程有关,因为可能是创建了过多的线程导致堆内存不够用。

那么如何查看线程的dump呢,我们可以借助JDK提供的jvisualvm工具(在jdk安装目录/bin路径下)。

我们可以先写一个main函数,让线程在一个对象上阻塞:

public static void main(String[] args) {
LockSupport.parkNanos(new Object(), TimeUnit.SECONDS.toNanos(1000));
}

之后我们打开jvisualvm,即找到该线程的名称,点击查看dump即可查看到了。下图红线处就是阻塞对象地址。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: