Java中的锁-park/unpark
park与unpark
在使用park与unpark的时候就在疑惑为什么先调用unpark时后park就不会阻塞,现在就总结一下原理
@Slf4j
public class ParkAndUnpark {public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(() -> {LockSupport.park();log.debug("T1线程");}, "T1");log.debug("Main线程");t1.start();Thread.sleep(2000);LockSupport.unpark(t1);}
}
可以看到这个还是比较符合我们正常情况,因为先执行的是park再执行的是unpark
那么先执行unpark再执行park呢?
@Slf4j
public class ParkAndUnpark {public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(() -> {log.debug("start");try {Thread.sleep(5000);} catch (InterruptedException e) {e.printStackTrace();}log.debug("park");LockSupport.park();log.debug("T1线程");}, "T1");log.debug("Main线程");t1.start();Thread.sleep(2000);LockSupport.unpark(t1);log.debug("unpark");}
}
你会发现其实也可以,你也会感到疑惑为什么呢?park加锁后没有unpark为啥还是可以执行?
特点
与 Object 的 wait/notify 相比
wait,notify 和 notifyAll 必须配合 Object Monitor 一起使用,而 park,unpark 不必
park & unpark 是以线程为单位来【阻塞】和【唤醒】线程,而 notify 只能随机唤醒一个等待线程,notifyAll
是唤醒所有等待线程,就不那么【精确】
park & unpark 可以先 unpark,而 wait & notify 不能先 notify
原理
每个线程都有自己的一个 Parker 对象,由三部分组成 _counter , _cond 和 _mutex 打个比喻
线程就像一个旅人,Parker 就像他随身携带的背包,条件变量就好比背包中的帐篷。_counter 就好比背包中
的备用干粮(0 为耗尽,1 为充足)
调用 park 就是要看需不需要停下来歇息
- 如果备用干粮耗尽,那么钻进帐篷歇息
- 如果备用干粮充足,那么不需停留,继续前进
调用 unpark,就好比令干粮充足
- 如果这时线程还在帐篷,就唤醒让他继续前进
- 如果这时线程还在运行,那么下次他调用 park 时,仅是消耗掉备用干粮,不需停留继续前进
因为背包空间有限,多次调用 unpark 仅会补充一份备用干粮
Parker起始状态
其中_counter = 0
调用park方法
- 当前线程调用park方法
- 检查 _counter ,本情况为 0,这时,获得 _mutex 互斥锁
- 线程进入 _cond 条件变量阻塞
调用unpark
- 调用 Unsafe.unpark(Thread-0) 方法,设置 _counter 为 1
- 唤醒 _cond 条件变量中的 Thread_0
- Thread-0 恢复运行
- 设置 _counter 为 0
为啥先调用unpark时,第一次park不会阻塞其原因就是调用时候设置了_counter 为 1 所以第一次不会阻塞,但是不管调用多少次unpark只会设置为1
Java中的锁-park/unpark相关推荐
- Java中的锁原理、锁优化、CAS、AQS详解
点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 作者:景小财 www.jianshu.com/p/e674ee68 ...
- 一篇blog带你了解java中的锁
前言 最近在复习锁这一块,对java中的锁进行整理,本文介绍各种锁,希望给大家带来帮助. Java的锁 乐观锁 乐观锁是一种乐观思想,即认为读多写少,遇到并发写的可能性低,每次去拿数据的时候都认为别人 ...
- Java中的锁[原理、锁优化、CAS、AQS]
点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达 今日推荐:用好Java中的枚举,真的没有那么简单!个人原创+1博客:点击前往,查看更多 作者:高广超 链接:https:/ ...
- Java中的锁原理、锁优化、CAS、AQS详解!
阅读本文大概需要 2.8 分钟. 来源:jianshu.com/p/e674ee68fd3f 一.为什么要用锁? 锁-是为了解决并发操作引起的脏读.数据不一致的问题. 二.锁实现的基本原理 2.1.v ...
- JAVA 中无锁的线程安全整数 AtomicInteger介绍和使用
转载自 http://blog.csdn.net/bigtree_3721/article/details/51296064 JAVA 中无锁的线程安全整数 AtomicInteger,一个提供原子操 ...
- 面试官让我讲讲Java中的锁,我笑了
转载自 面试官让我讲讲Java中的锁,我笑了 在读很多并发文章中,会提及各种各样锁如公平锁,乐观锁等等,这篇文章介绍各种锁的分类.介绍的内容如下: 公平锁/非公平锁 可重入锁 独享锁/共享锁 互斥锁 ...
- Java中的锁(转)
Java中的锁 锁像synchronized同步块一样,是一种线程同步机制,但比Java中的synchronized同步块更复杂.因为锁(以及其它更高级的线程同步机制)是由synchronized同步 ...
- 一文足以了解什么是 Java 中的锁
作者 | cxuan 责编 | Elle Java 锁分类 Java 中的锁有很多,可以按照不同的功能.种类进行分类,下面是我对 Java 中一些常用锁的分类,包括一些基本的概述 从线程是否需要对资 ...
- 关于Java中的锁,看这一篇就够了(总结篇)
文章目录 锁的概念 锁的分类 一.什么是悲观锁? Java中的悲观锁有哪些 synchronized 基于AQS的实现类 二.什么是乐观锁? Java中的乐观锁有哪些 Valotile Java内存模 ...
最新文章
- indows上的android开发环境软件架构5
- html表单c 后台如何接受,前台提交整个表单数据,后台实体类接收
- UBUNTU安装搜狗
- jquery form 序列化
- 【原创】字符串工具类--找出单元字符串
- etrace 跟踪程序函数动态执行流程
- 虚拟机批量安装LINUX,基于vmware workstation的 pxe + kickstart批量安装linux
- aix如何安装mysql_AIX下安装Mysql
- mysql key_block_size_Mysql入门mysql Key_buffer_size参数的优化设置
- python函数编程训练题_Python文件与函数练习题
- python3示例_Python3 实例(七)
- oracle 10g 企业管理器无法打开解决方法
- lamba List 转 Map
- android 9格式吗,Android Studio中关于9-patch格式图片的编译错误
- 数据结构练习题之树和图(附答案与解析)
- 6000万条GitHub帖子告诉你:工作状态与表情符号强相关
- 【转】MEF程序设计指南四:使用MEF声明导出(Exports)与导入(Imports)
- jieba库初识与运用
- matlab中标准化降水指数程序,标准化降水指数(SPI)计算程序
- html 简繁转换 批量,繁简文件批量互转程序