Java多线程与锁
锁分类
顺序划分
名称 | 说明 |
---|---|
公平锁 | 线程不会饿死,效率低 |
非公平锁 | 部分线程会饿死,效率高 |
注意事项
- synchronized是非公平锁,并且它无法实现公平锁
- 公平锁可以通过new ReentrantLock(true)来实现;非公平锁可以通过new ReentrantLock(false)或者默认构造函数new ReentrantLock()实现
多线程划分
名称 | 说明 |
---|---|
互斥锁 | 对应 ------> 悲观锁 |
非互斥锁 | 对应 ------> 乐观锁 |
注意事项
- synchronized就是互斥锁
递归划分
名称 | 说明 |
---|---|
可重入锁 | 允许进入自己持有的锁 |
不可重入锁 | 不允许进入自己持有的锁,需释放锁 |
编译划分
名称 | 说明 |
---|---|
锁消除 | 代码要求同步,但被检测到无需加锁 |
锁粗化 | 同步块代码范围不要太大,避免在没有线程竞争的场景下导致性能损耗 |
使用位置划分
名称 | 说明 |
---|---|
类锁 | 使用字节码文件作为锁(.class) |
对象锁 | 使用对象作为锁(this) |
设计理念划分
名称 | 说明 |
---|---|
悲观锁 | 认为多线程下会认为都会修改数据 |
乐观锁 | 认为多线程下不会修改数据,CAS无锁算法 |
数据库划分
名称 | 说明 |
---|---|
共享锁 | 读锁 |
排它锁 | 写锁 |
效率划分
名称 | 说明 |
---|---|
无锁 | |
偏向锁 | 单线程访问,自动获取锁 |
轻量级锁 | 多线程访问,自旋获取锁,不阻塞 |
重量级锁 | 多线程访问,自旋获取锁,但自旋一定次数后变为阻塞,性能低 |
注意事项
- 自旋锁:循环获取锁,减少上下文切换,但消耗CPU
并发划分
名称 | 说明 |
---|---|
死锁 | 多线程资源竞争导致互相等待,阻塞 |
活锁 | 不断尝试获取锁,不阻塞 |
存储划分
名称 | 说明 |
---|---|
分段锁 | 分段加锁,提高并发 |
注意事项
- jdk8之前的ConcurrentHashMap 的分段锁(Segment)
- jdk8之后采用CAS+synchronized。通过hashCode计算到索引后对数据分段加锁
相关参考
https://www.cnblogs.com/zt007/p/10456926.html