李林超博客
首页
归档
留言
友链
动态
关于
归档
留言
友链
动态
关于
首页
Java
正文
19.并发编程之park与unpark基本使用
Leefs
2022-10-22 PM
1528℃
0条
[TOC] ### 一、概念 LockSupport是JDK中比较底层的类,用来创建锁和其他同步工具类的基本线程阻塞原语。 park,unpark这两个方法都是LockSupport类名下的方法,park用来暂停线程,unpark用来将暂停的线程恢复。 先park再unpark的方式是容易理解的。但还有一个场景,先unpark后再次执行park方法,也不会阻塞调用了park方法的线程。 理解为park方法就是校验获取一个通行令牌,而unpark方法是获取到一个通行令牌的过程。先执行unpark方法,代表先获得了通行令牌。那么在另一个线程调用park方法时,校验到这个令牌存在,消耗掉这个令牌然后就可以继续往下走。 ### 二、LockSupport函数列表 ```java public class LockSupport { // 返回提供给最近一次尚未解除阻塞的 park 方法调用的 blocker 对象,如果该调用不受阻塞,则返回 null。 static Object getBlocker(Thread t); // 为了线程调度,禁用当前线程,除非许可可用。 static void park(); // 为了线程调度,在许可可用之前禁用当前线程。 static void park(Object blocker); // 为了线程调度禁用当前线程,最多等待指定的等待时间,除非许可可用。 static void parkNanos(long nanos); // 为了线程调度,在许可可用前禁用当前线程,并最多等待指定的等待时间。 static void parkNanos(Object blocker, long nanos); // 为了线程调度,在指定的时限前禁用当前线程,除非许可可用。 static void parkUntil(long deadline); // 为了线程调度,在指定的时限前禁用当前线程,除非许可可用。 static void parkUntil(Object blocker, long deadline); // 如果给定线程的许可尚不可用,则使其可用。 static void unpark(Thread thread); } ``` 说明:LockSupport是通过调用Unsafe函数中的接口实现阻塞和解除阻塞的。 ### 三、基本使用 | 方法 | 说明 | | -------------------------------- | ------------------ | | LockSupport.park(); | 暂停当前线程 | | LockSupport.unpark(暂停线程对象) | 恢复某个线程的运行 | + **先 park 再 unpark** ```java import lombok.extern.slf4j.Slf4j; import java.util.concurrent.locks.LockSupport; import static com.lilinchao.concurrent.utils.Sleeper.sleep; /** * Created by lilinchao * Date 2022/10/22 * Description 先 park 再 unpark */ @Slf4j(topic = "c.Test01") public class Test01 { public static void main(String[] args) { Thread t1 = new Thread(() -> { log.debug("start..."); sleep(1); log.debug("park..."); LockSupport.park(); log.debug("resume..."); },"t1"); t1.start(); sleep(2); log.debug("unpark..."); LockSupport.unpark(t1); } } ``` **输出结果** ``` 21:16:35.017 c.Test01 [t1] - start... 21:16:36.019 c.Test01 [t1] - park... 21:16:37.017 c.Test01 [main] - unpark... 21:16:37.017 c.Test01 [t1] - resume... ``` - **先 unpark 再 park** ```java import lombok.extern.slf4j.Slf4j; import java.util.concurrent.locks.LockSupport; import static com.lilinchao.concurrent.utils.Sleeper.sleep; /** * Created by lilinchao * Date 2022/10/22 * Description 先 unpark 再 park */ @Slf4j(topic = "c.Test02") public class Test02 { public static void main(String[] args) { Thread t1 = new Thread(() -> { log.debug("start..."); sleep(2); log.debug("park..."); LockSupport.park(); log.debug("resume..."); },"t1"); t1.start(); sleep(1); log.debug("unpark..."); LockSupport.unpark(t1); } } ``` **输出结果** ``` 21:18:03.732 c.Test02 [t1] - start... 21:18:04.731 c.Test02 [main] - unpark... 21:18:05.735 c.Test02 [t1] - park... 21:18:05.735 c.Test02 [t1] - resume... ``` #### 与Object的wait¬ify对比 + wait,notify 和 notifyAll 必须配合 Object Monitor 一起使用,而 park,unpark 不必; + park & unpark 是以线程为单位来【阻塞】和【唤醒】线程,而 notify 只能随机唤醒一个等待线程,notifyAll是唤醒所有等待线程,就不那么【精确】; + park & unpark 可以先 unpark,而 wait & notify 不能先 notify。 ### 四、原理 每个线程都会关联一个 Parker 对象,每个 Parker 对象都各自维护了三个角色:`_counter`(计数器)、 `_mutex`(互斥量)、`_cond`(条件变量)。 #### 4.1 情况一:先调用park,再调用unpark ##### park 操作 ![19.并发编程之park与unpark基本使用01.jpg](https://lilinchao.com/usr/uploads/2022/10/2839616086.jpg) 1. 当前线程调用 Unsafe.park() 方法 2. 检查 _counter ,本情况为 0,这时,获得 _mutex 互斥锁 3. 线程进入 _cond 条件变量阻塞 4. 设置 _counter = 0 ##### unpark 操作 ![19.并发编程之park与unpark基本使用02.jpg](https://lilinchao.com/usr/uploads/2022/10/3975078615.jpg) 1. 调用 Unsafe.unpark(Thread_0) 方法,设置 _counter 为 1 2. 唤醒 _cond 条件变量中的 Thread_0 3. Thread_0 恢复运行 4. 设置 _counter 为 0 #### 4.2 情况二:先调用unpark,再调用park ![19.并发编程之park与unpark基本使用03.jpg](https://lilinchao.com/usr/uploads/2022/10/2011237042.jpg) 1. 调用 Unsafe.unpark(Thread_0) 方法,设置 _counter 为 1 2. 当前线程调用 Unsafe.park() 方法 3. 检查 _counter ,本情况为 1,这时线程无需阻塞,继续运行 4. 设置 _counter 为 0 *附参考文章地址* *《黑马程序员之并发编程》*
标签:
并发编程
非特殊说明,本博所有文章均为博主原创。
如若转载,请注明出处:
https://lilinchao.com/archives/2511.html
上一篇
18.并发编程之保护性暂停模式
下一篇
20.并发编程之多把锁问题
评论已关闭
栏目分类
随笔
2
Java
326
大数据
229
工具
31
其它
25
GO
47
NLP
4
标签云
并发编程
FileBeat
Tomcat
机器学习
BurpSuite
MyBatis
Linux
Livy
DataX
锁
MySQL
Elasticsearch
数学
DataWarehouse
Kibana
GET和POST
CentOS
Zookeeper
Elastisearch
RSA加解密
Git
Typora
Http
Hive
SpringBoot
算法
Jquery
查找
Hbase
Python
友情链接
申请
范明明
庄严博客
Mx
陶小桃Blog
虫洞
评论已关闭