目录
常用锁
synchronized
ReentrantLock
ReadWriteLock
Semaphore
常用锁的介绍可参见:Java常用锁机制简介
synchronized
了解
对于初学者,想了解synchronized
的使用的话,可以参考Java中synchronized的用法
总结
- 按加锁范围大小,分为类锁和对象锁。
- 按加锁方法,分为代码块加锁和方法加锁。
关于类锁和对象锁需要着重区分下。对象锁只会影响单个对象,而类锁会影响该类下所有的对象。
进阶
synchronized
进阶学习的话,需要了解下其实现原理:Synchronized及其实现原理
总结
- 每个对象都有个monitor对象,加锁就是在竞争monitor对象
- 代码块加锁是在前后分别加上
monitorenter
和monitorexit
指令来实现的- 方法加锁是通过一个标记位来判断的
再进阶
关于“synchronized
比较慢”的误解
在Java1.5中,synchronized是一个重量级操作,需要调用操作系统相关接口,性能是低效的,有可能给线程加锁消耗的时间比有用操作消耗的时间更多。到了Java1.6,synchronized进行了很多的优化,有适应自旋、锁消除、锁粗化、轻量级锁及偏向锁等,效率有了本质上的提高。在之后推出的Java1.7与1.8中,均对该关键字的实现机理做了优化。
关于锁的优化,可以参考
总结
- 引入了偏向锁和轻量级锁。都是在对象头中有标记位,不需要经过操作系统加锁
- 锁可以从偏向锁升级到轻量级锁,再升级到重量级锁。这种升级过程叫做锁膨胀
- JDK 1.6中默认是开启偏向锁和轻量级锁,可以通过
-XX:-UseBiasedLocking
来禁用偏向锁
ReentrantLock
了解
对于初学者,了解ReentrantLock
,可通过参考ReentrantLock的使用
ReentrantLock
的使用还是比较简单的
进阶
要深入理解ReentrantLock
,就需要知道其实现原理。参考文章:
总结
ReentrantLock
是通过大名鼎鼎的AQS来实现的。弄懂了AQS,就弄懂了ReentrantLock
ReentrantLock
分为公平锁和非公平锁引申
除了ReentrantLock
,CountDownLatch
和Semaphore
也是通过AQS实现的。关于AQS,可参考未完待续...
synchronized和ReentrantLock的对比
synchronized
和ReentrantLock
的对比是个永恒的话题。这两个常用的加锁方式有同有异,互为补充。ReentrantLock
的出现不是为了替代synchronized
,而是弥补synchronized
的不足。
关于synchronized
和ReentrantLock
的异同,网上的文章多如牛毛。比较好的有:
总结
synchronized
能做的,ReentrantLock
都能做,并且还能做更多。但是synchronized
依然有用武之地ReentrantLock
相比synchronized
的优势是可中断、公平锁、多个锁。这种情况下需要使用ReentrantLock
。只要是synchronized
能做到的,还是使用synchronized
。
锁分类
Java中的锁有很多概念和术语,如可重入锁、公平锁、偏向锁等。这些术语中,有些指的是同一种锁,有些是表示的锁的特征。如synchronized
同时是可重入锁、非公平锁、互斥锁等。
这些术语只是从不同的纬度来描述锁的应用场景。只有了解的这些术语,术语所指代的特征,以及常用锁跟这些特征的关系,才能熟练并且合理地使用锁。
可重入锁
参考可重入锁
总结
- 不可重入的话,一个锁在嵌套中使用会把自己锁死
synchronized
和ReentrantLock
都是可重入锁,可放心使用
公平锁/非公平锁
总结
synchronized
是非公平锁,ReentrantLock
默认构造函数也是非公平锁- 非公平锁的性能比公平锁要高很多
互斥锁/共享锁
总结
- 互斥和共享的概念比较简单,并且在任何语言中都存在
悲观锁/乐观锁
总结
- 悲观锁和乐观锁并非是一种实际的锁,而是指一种加锁的概念
- 这种也并非java独有,在其他语言和数据库中都有广泛的应用
- 悲观锁在java中一般指代常见的各种锁
- 乐观锁在java中一般指代CAS操作
偏向锁/轻量级锁/重量级锁
参考:
总结
- 偏向锁、轻量级锁是针对重量级锁做优化而提出来的概念和实施方案
- 这些优化大部分情况下对于开发来讲是透明的,默认开启
分段锁
参考java多线程 -- ConcurrentHashMap 锁分段机制
总结
- 分段锁也并非一种实际的锁,而是一种思想
- ConcurrentHashMap是学习分段锁的最好实践
自旋锁
参考自旋锁
总结
- 自旋锁也是一种思想,一般需要配合CAS使用
java.util.concurrent.atomic
包下的原子类是自旋锁的很好的实践
锁优化
锁优化分为两种,一种是JVM开发团队对锁的优化,这个对应用开发人员来讲,一般不需要关心。另一种是应用开发人员需要关注的锁优化,这属于开发素养的范畴。
JVM锁优化
总结
- 锁粗化
- 锁消除
应用开发锁优化
总结
- 锁优化是JVM实现的对锁的一种加速,算是JVM开发人员给应用开发人员提供的福利
- 大部分情况下,应用开发人员不需要关心锁优化。