ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

浅谈LockSupport工具类

2021-01-09 12:04:18  阅读:294  来源: 互联网

标签:调用 浅谈 park LockSupport unpark 线程 工具 许可


Java的并发包是基于AQS (AbstractQueuedSynchronizer)框架的,AQS框架需要借助于两个工具类:

  • Unsafe(提供CAS操作)
  • LockSupport(提供park/unpark操作)

LockSupport的使用

LockSupport定义了一组公共静态方法,这些方法提供了最基本的线程阻塞和唤醒功能。LockSupport定义了一组以park开头的方法用来阻塞当前线程,以及unpark(Thread thread)方法来唤醒一个被阻塞的线程。

在Java6中,LockSupport增加了三个带有blocker的方法。参数blocker用来指出当前线程在等待的对象,即阻塞对象,该对象主要用于问题排查和系统监控。

public static void park(Object blocker); // 暂停当前线程
public static void parkNanos(Object blocker, long nanos); // 暂停当前线程,不过有超时时间的限制
public static void parkUntil(Object blocker, long deadline); // 暂停当前线程,直到某个时间

现在通过具体代码看看是如何使用的

LockSupport的原理(以park和unpark为例说明)

1. 源码分析

归根结底,LockSupport.park()和LockSupport.unpark(Thread thread)调用的是Unsafe类中的native代码:

//LockSupport中
public static void park() {
        UNSAFE.park(false, 0L);
    }

public static void unpark(Thread thread) {
        if (thread != null)
            UNSAFE.unpark(thread);
    }

Unsafe类中的对应方法:

//park
public native void park(boolean isAbsolute, long time);
    
//unpack
public native void unpark(Object var1);

Unsafe.park()和Unsafe.unpark()的底层,在Linux系统下,是用的POSIX的线程库pthread中的mutex(互斥量),condition(条件变量)来实现的,即互斥锁+条件变量。mutex和condition保护了一个_counter的变量,当park时,这个变量被设置为0,当unpark时,这个变量被设置为1。

2. 特性和思想

2.1 许可

LockSupport类使用了一种名为permit(许可)的概念来做到阻塞和唤醒线程的功能,可以把许可看成是一种(0,1)信号量,但这个许可的累加上限是1。初始时,permit为0,当调用unpark()方法时,线程的permit加1,当调用park()方法时,如果permit为0,则调用线程进入阻塞状态。也就是说,park/unpark的设计原理核心是“许可”:park是等待一个许可,unpark是为某线程提供一个许可。如果某线程A调用park,那么除非另外一个线程调用unpark(A)给A一个许可,否则线程A将阻塞在park操作上。

但是这个“许可”是不能叠加的,“许可”是一次性的。比如线程B连续调用了三次unpark函数,当线程A调用park函数就使用掉这个“许可”,如果线程A再次调用park,则进入等待状态。

2.2 顺序

park和unpark的先后顺序并不是那么严格,即unpark操作可以再park操作之前。这时候规则是这样的:

  1. unpark调用时,如果当前线程还未进入park,则许可为true
  2. park调用时,判断许可是否为true,如果是true,则继续往下执行;如果是false,则等待,直到许可为true

LockSupport和wait/notify的区别

  • LockSupport以线程为操作对象更符合阻塞线程的直观定义。
  • 操作更精准,可以准确地唤醒某一个线程,增加了灵活性。而notify随机唤醒一个线程,notifyAll唤醒所有等待的线程。
  • wait和notify都是Object中的方法,在调用这两个方法前必须先获得对象的锁,但是park不需要获取某个对象的锁就可以锁住线程。

参考资料

LockSupport详解

LockSupport的用法及原理

Java多线程进阶(五)—— J.U.C之locks框架:LockSupport

 

标签:调用,浅谈,park,LockSupport,unpark,线程,工具,许可
来源: https://blog.csdn.net/qq_42052956/article/details/112389030

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有