当前位置:网站首页>高级并发编程系列九(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
边栏推荐
- Chinese sub forum of | 2020 PostgreSQL Asia Conference: Pan Juan
- FreeSWITCH视频会议“标准”解决方案
- 滴滴的分布式ID生成器(Tinyid),好用的一批
- Kubernetes (1): introduction to kubernetes
- Windows 10 Bluetooth management page 'add Bluetooth or other devices' option click no response solution
- Insomnia all night
- 课堂练习
- Python3 operating gitlab
- Classroom exercises
- Vue: Axios uses this pointer
猜你喜欢
一种超参数优化技术-Hyperopt
VARCHART XGantt如何在日历上表示工作日
cubemx做stm32 USB开发
ImageMagick - 添加水印
Classroom exercises
DOM node operation
Exclusive interview with alicloud database of | 2020 PostgreSQL Asia Conference: Wang Xu
Insomnia all night
2020-11-06: go, let's talk about the scheduler.
And how to solve the conflict between pop-up menu and pop-up menu
随机推荐
课堂练习
Git SSH bad permissions
K-vim installation and the ycmd server shut down (restart with ': ycmrestartserver')
If you want to forget the WiFi network you used to connect to your Mac, try this!
[graffiti footprints of Internet of things] mainstream communication mode of Internet of things
Is blazor ready to serve the enterprise?
Two dimensional code location and alarm system of Expressway
Knowledge competition of garbage classification
How to add modules to nginx image?
OpenCV計算機視覺學習(10)——影象變換(傅立葉變換,高通濾波,低通濾波)
Dynamsoft barcode reader v7.5!
Analysis of the original code of [QT] qthread
带你深入了解 GitLab CI/CD 原理及流程
git 提交规范
9.集群之间服务通信 RoutingMesh
Three steps to understand Kerberos Protocol easily
Come on in! Take a few minutes to see how reentrantreadwritelock works!
2020-11-06:go中,谈一下调度器。
A kind of super parameter optimization technology hyperopt
MongoDB下,启动服务时,出现“服务没有响应控制功能”解决方法