Java并发编程实战 第13章 显式锁
接口Lock的实现类:
ReentrantLock, ReentrantReadWriteLock.ReadLock, ReentrantReadWriteLock.WriteLock
ReentrantLock
java5.0之前只有synchronize和volatile,ReentrantLock是5.0增加的。
ps:synchronize使用的监视器锁不是通过ReentrantLock实现的,是一种独特的机制。在5.0中它的性能要比ReentrantLock低很多,在6.0中它的性能也比ReentrantLock也要低一点。
ReentrantLock的独有功能:
- 可实现轮询
- 可配置为定时返回
- 可配置为响应中断
- 可配置为公平锁
注意:lock的unlock必须在finally中。
轮询和定时都是通过tryLock(time)方法来实现的。
while(true)
{
boolean success = lock.tryLock(time);
if success
{
//获得了锁
//执行代码
break;
}
}
关于公平锁:
此类的构造方法接受一个可选的公平 参数。当设置为 true 时,在多个线程的争用下,这些锁定倾向于将访问权授予等待时间最长的线程。否则此锁定将无法保证任何特定访问顺序。与采用默认设置(使用不公平锁定)相比,使用公平锁定的程序在许多线程访问时表现为很低的总体吞吐量(即速度很慢,常常极其慢),但是在获得锁定和保证锁定分配的均衡性时差异较小。不过要注意的是,公平锁定不能保证线程调度的公平性。还要注意的是,未定时的 tryLock 方法并没有使用公平设置。因为即使其他线程正在等待,只要该锁定是可用的,此方法就可以获得成功。
synchronize和ReentrantLock的选择
ReentrantLock在性能上似乎优于内置锁,但是内置锁仍然具有很大的优势。内置锁为许多开发人员所熟悉,并且简介紧凑,而且许多现有的程序都已经使用了内置锁,如果将这两种机制混合使用,那么不仅容易令人困惑,也容易发生错误。
而且synchronize更加的简单,JVM会对它有特殊的优化。
所以作者建议优先选择synchronize。
读写锁
写锁独占读写操作。读锁之间可以共享。
读写锁本身的实现会有负担,所以一般在读操作比较多的情况下使用。如果不是这种情况,最好测试后再做决定。
ReentrantReadWriteLock:
此类具有以下属性:
- 获取顺序
当设置为公平锁时,线程利用一个近似到达顺序的策略来争夺进入。当释放写入锁定后,将写入锁定分配给等待时间最长的单个写入者,如果有一个等待时间比所有写入者更长的读取者,则将读取锁定分配给读取者 set。当非公平地构造线程时,则不需要按照到达顺序进入锁定。不管是哪一种情况,如果读取者处于活动状态,而某个写入者进入锁定状态,那么在获取写入者并释放写入锁定之前,不会将读取锁定授予任何后续的读取者。我的理解:也就是说,写入锁具有优先获取锁的特权,虽然在公平锁的情况下,这个特权会削弱,但是依然有。
- 重入
此锁定允许读取者和写入者按照 ReentrantLock 的样式重新获取读取锁定或写入锁定。在写入线程保持的所有写入锁定都已经释放后,才允许写入者使用它们。
- 锁定降级
重入还允许从写入锁定降级为读取锁定,其实现方式是:先获取写入锁定,然后获取读取锁定,最后释放写入锁定。但是,从读取锁定升级到写入锁定是不可能的。
- 锁定获取的中断
读取锁定和写入锁定都支持锁定获取期间的中断。
- Condition 支持
写入锁定提供了一个 Condition 实现,对于写入锁定来说,该实现的行为与 ReentrantLock.newCondition() 提供的 Condition 实现对 ReentrantLock 所做的行为相同。当然,此 Condition 只能用于写入锁定。
读取锁定不支持 Condition,readLock().newCondition() 会抛出 UnsupportedOperationException。
- 序列化
此类行为的序列化方式与内置锁定的相同:反序列化的锁定处于解除锁定状态,无论序列化该锁定时其状态如何。
Java并发编程实战 第13章 显式锁的更多相关文章
- Java并发编程实战---第六章:任务执行
废话开篇 今天开始学习Java并发编程实战,很多大牛都推荐,所以为了能在并发编程的道路上留下点书本上的知识,所以也就有了这篇博文.今天主要学习的是任务执行章节,主要讲了任务执行定义.Executor. ...
- 【Java并发编程实战】----- AQS(二):获取锁、释放锁
上篇博客稍微介绍了一下AQS,下面我们来关注下AQS的所获取和锁释放. AQS锁获取 AQS包含如下几个方法: acquire(int arg):以独占模式获取对象,忽略中断. acquireInte ...
- Java并发编程实战 第16章 Java内存模型
什么是内存模型 JMM(Java内存模型)规定了JVM必须遵循一组最小保证,这组保证规定了对变量的写入操作在何时将对其他线程可见. JMM为程序中所有的操作定义了一个偏序关系,称为Happens-Be ...
- Java并发编程实战 第10章 避免活跃性危险
死锁 经典的死锁:哲学家进餐问题.5个哲学家 5个筷子 如果没有哲学家都占了一个筷子 互相等待筷子 陷入死锁 数据库设计系统中一般有死锁检测,通过在表示等待关系的有向图中搜索循环来实现. JVM没有死 ...
- 【Java并发编程实战】-----“J.U.C”:锁,lock
在java中有两种方法实现锁机制,一种是在前一篇博客中([java7并发编程实战]-----线程同步机制:synchronized)介绍的synchronized,而另一种是比synchronized ...
- 【java并发编程实战】第一章笔记
1.线程安全的定义 当多个线程访问某个类时,不管允许环境采用何种调度方式或者这些线程如何交替执行,这个类都能表现出正确的行为 如果一个类既不包含任何域,也不包含任何对其他类中域的引用.则它一定是无状态 ...
- Java并发编程实战 第8章 线程池的使用
合理的控制线程池的大小: 下面内容来自网络.不过跟作者说的一致.不想自己敲了.留个记录. 要想合理的配置线程池的大小,首先得分析任务的特性,可以从以下几个角度分析: 任务的性质:CPU密集型任务.IO ...
- 《Java并发编程实战》第二章 线程安全性 读书笔记
一.什么是线程安全性 编写线程安全的代码 核心在于要对状态訪问操作进行管理. 共享,可变的状态的訪问 - 前者表示多个线程訪问, 后者声明周期内发生改变. 线程安全性 核心概念是正确性.某个类的行为与 ...
- 《Java并发编程实战》第二章 线程安全 札记
一个.什么是线程安全 编写线程安全的代码 其核心是管理国事访问的操作. 共享,可变的状态的訪问 - 前者表示多个线程訪问, 后者声明周期内发生改变. 线程安全性 核心概念是正确性.某个类的行为与其规范 ...
随机推荐
- Kotlin之注释
kotliin中注释和java注释是一样的,支持单行注释和多行注释,但kotlin支持嵌套,java不支持
- Python线程和协程
写在前面 好好学习 天天向上 一.线程 1.关于线程的补充 线程:就是一条流水线的执行过程,一条流水线必须属于一个车间: 那这个车间的运行过程就是一个进程: 即一个进程内,至少有一个线程: 进程是一个 ...
- robotFramework——FOR循环语句
robotframework支持FOR循环语句,语法和Python的语法基本相同,但robotframework中,“FOR”关键字前面需要增加一个“:”,写成“:FOR”,其它与Python的语法相 ...
- Elasticsearch 6.2.3版本 同一个index新增type报错 Rejecting mapping update to [website] as the final mapping would have more than 1 type: [blog2, blog]
在website的index下已经存在一个名为blog的type.想在website下,新增一个名为blog2的type. 执行语句如下: PUT /website/blog2/1 { "t ...
- ffi模块——node调用动态链接库(.so/.dll文件)
参考资料1:[https://www.npmjs.com/package/ffi] 参考资料2:[http://imweb.io/topic/57732fbef0a5487b05f325bf] 参考资 ...
- JavaScript Source Maps浅析
阅读目录 有用的链接 Link: 原文链接 译文开始: 对网站进行性能优化对一个最容易的方法就是把JS和CSS进行打包压缩.但是当你需要调试这些压缩文件中的代码的时候,会发生什么?可能会是一场噩梦.但 ...
- 运行RGB-DSLAM的一些报错及处理方法
part 4 报错‘create’ is not a menber of 'CV::FeatureDetector::create(detector.c_str()); 查看opencv版本 修改Cm ...
- mysql 关键字大全
mysql无论表名,还是字段名都应该避开mysql关键字. 如字段使用关键字,sql查询需加上` `. 查询插件,当使用关键字,会报错. usage
- HDU-1204-糖果大战
题目描述 生日\(Party\)结束的那天晚上,剩下了一些糖果,\(Gandon\)想把所有的都统统拿走,\(Speakless\)于是说:"可以是可以,不过我们来玩\(24\)点,你不是已 ...
- 786B - Legacy(线段树 + 最短路)线段树优化建图
题意: 就是给定一张n nn个点的图,求源点s ss到每个点的单源最短路.这张图共有q组边,连边方式有3种: a→b ,边权为w的单向边:a→[l,r] ,即a到连续区间[l,r]中的每一个点都有一条 ...