当前位置:网站首页>高级并发编程系列九(Lock接口分析)
高级并发编程系列九(Lock接口分析)
2020-11-07 18:55:00 【yhhitall】
1.考考你
许多朋友在入门java并发编程的时候,如果说到控制线程安全,一定对synchronized关键字非常熟系。synchronized关键字表示同步加锁,就是我正在用,你得等我用完后再来的意思。
比如在 高级并发编程系列七(锁入门)这一篇,我们对add_i变量自增操作,同步加锁一样,让add_i变量在同一时刻,只会被一个线程操作,从而线程安全。
/**
* addI方法,实现add_i变量自曾操作
*/
public synchronized static void addI(){
add_i ++;
}
这么说,你可能就会有疑问了:既然synchronized关键字可以实现加锁,保障线程安全了。那么java的设计者为什么还要在juc包中提供锁接口Lock,以及Lock接口的相关实现呢?这不是既生瑜、何生亮吗?不好,难道周瑜孔明的故事还要再演一遍!
其实不是的,虽然有了synchronized关键字,我们说再有Lock接口和实现并不多余,那么接下来我们就一起来说道说道。
之所以有了synchronized关键字,还需要提供Lock接口,主要基于这么几个因素:
-
synchronized同步加锁内部由jdk控制,是非公平锁。实际应用中,有时候我们需要公平锁,但是它做不到。一句话概括:不够灵活
-
synchronized同步加锁内部由jdk控制,不可中断。使用起来比较霸道,一旦获取锁的线程未执行完,外部不可操控,不可中断获取锁线程。一句话概括:不够灵活
-
synchronized同步加锁内部由jdk控制,不能获取到加锁状态,即一个线程A获取到锁以后,那么需要同一个锁的线程BCD只能被阻塞等待,使用起来不够灵活。比如说做不到线程A获取锁以后,线程B来尝试获取锁,如果获取不到锁,线程B可以去做别的事情,不需要傻傻的等在这里。一句话概括:不够灵活
可以看到,综上所述我们对synchronized关键字的印象是:不够灵活。这里需要注意,有的朋友在说起synchronized关键字,与Lock锁区别的时候,会从性能的角度去看,事实上从jdk1.6以后,jvm内部专门实现了锁优化,两者在性能上几乎没有差异了。主要的区别还是synchronized不够灵活。
那么我们再来看一下,针对synchronized不灵活的地方,Lock接口都提供了哪些解决方案:
-
synchronized锁是非公平锁。Lock接口常用的实现类ReentrantLock,在构造锁对象的时候,我们可以指定构造公平锁,还是非公平锁,实现按需构造
-
synchronized锁是不可中断锁。Lock接口提供了lockInterruptibly()方法,支持中断操作
-
synchronized锁获取不到加锁状态。Lock接口提供了tryLock()方法,用于返回获取锁状态。如果线程A已经获取到锁,那么线程B通过tryLock尝试获取锁,获取不到不需要被阻塞
-
另外Lock接口的实现类,通过在读写锁ReentrantReadWriteLock类中的读锁ReadLock,实现了共享锁。所谓共享锁读锁,即是大家都是读操作,不用太见外,你可以读,我可以读,大家读才是真的读。
通过以上关于Lock接口的描述,你是不是越来越爱Lock锁接口了,我想是的。那么接下来,我们一起来看一下Lock接口的设计,以及基本用法。
2.案例
2.1.Lock接口源码
通过以上分析描述,我想我们都会很好奇,Lock接口到底是如何设计的,它需要给我们提供哪些能力呢?对吧,我们一起来尝试思考一下:
-
需要一个加锁的操作,因此应该有加锁方法:lock
-
任务执行完成后,需要一个释放锁的操作,因此应该有释放锁的方法:unlock
-
根据我们上面与synchronized对比,Lock需要支持获取锁状态,如果尝试获取不到锁,不需要阻塞线程,因此应该有尝试获取锁方法:tryLock
-
根据我们上面与synchronized对比,Lock需要支持中断操作,因此应该有支持中断操作的加锁方法:lockInterruptibly
-
以上应该是我们可以直观想到的Lock基础能力,事实上Lock接口通过不同的实现类,提供了更强大的能力。我们后续通过案例慢慢来展示,暂时你先不需要太关心
接下来让我们看一下,Lock接口的源码截图,除了看图以外,我建议你打开jdk的源码,看一看Lock接口源码,里面有很详细的源码注释,这是一种挺好的学习方式。
2.2.Lock接口编程模板
在你的应用中,如果是通过synchronized关键字加锁的话,你一定还有印象:使用synchronized关键字,我们并不需要释放锁的操作,一切都有jvm来控制。
但是如果你选择了更加灵活的Lock锁方式,记得一定要:配套释放锁操作,千万不要只管生、不管养那就麻烦了,那么等待你的应该就是deadLock(死锁)了。
接下来我先给一个通用的Lock锁使用模板,你需要留意try{...}finally{...}语句块。
这里我们暂时不展开实际的使用案例,实际应用案例,我们将放在下一篇在跟你一起来学习。
/**
* addI方法,实现add_i变量自曾操作
* 通过Lock加锁
*/
public static void addI(){
// 加锁
lock.lock();
try{
// 业务操作
add_i ++;
}finally{
// 释放锁
lock.unlock();
}
}
版权声明
本文为[yhhitall]所创,转载请带上原文链接,感谢
https://my.oschina.net/u/4450329/blog/4707654
边栏推荐
- [original] the impact of arm platform memory and cache on the real-time performance of xenomai
- Windows 10 Bluetooth management page 'add Bluetooth or other devices' option click no response solution
- git 提交规范
- HMS core push service helps e-commerce app to carry out refined operation
- Blazor 準備好為企業服務了嗎?
- ImageMagick - add watermark
- 【原創】ARM平臺記憶體和cache對xenomai實時性的影響
- Exclusive interview with Yue Caibo
- 滴滴的分布式ID生成器(Tinyid),好用的一批
- Mac新手必备小技巧
猜你喜欢
After pulling four message queues into a group, they quarreled
vue踩坑:axios使用this指针
CI / CD of gitlab continuous integrated development environment
.NETCore3.1+Vue.js打造的低代码工作流引擎
C enumerates the differences between permissions |, and |
New features of vue3
Developing STM32 USB with cubemx
How to add modules to nginx image?
LEADTOOLS如何检测,读取和写入条形码
Benefits and functions of auto maintenance app development
随机推荐
Let you have a deep understanding of gitlab CI / CD principle and process
Win7 AppCrash (solution)
2020-11-06: go, let's talk about the scheduler.
8.Swarm创建维护和水平扩展Service
Two dimensional code location and alarm system of Expressway
python3操作gitlab
K-vim installation and the ycmd server shut down (restart with ': ycmrestartserver')
【QT】QThread原始碼淺析
Git SSH bad permissions
Mac新手必备小技巧
LEADTOOLS如何检测,读取和写入条形码
Jenkins入门(二)声明式流水线Jenkins Pipeline
Python3 operating gitlab
C# 枚举权限 |和||,&和&&的区别
RECH8.0版本学习 days 12 rh134部分
Implementation of nginx version of microservice architecture
Git SSH bad permissions
嘉宾专访|2020 PostgreSQL亚洲大会中文分论坛:岳彩波
Classroom exercises
插件Bilibili新版0.5.5