1.悲观锁和乐观锁:处理所冲突的态度(原因)
悲观锁:预期锁冲突的概率很高,做的工作更多,付出成本更多,更低效
乐观锁:与其所冲突的概率很低,做的工作更少,付出成本很低,更高效
2.重量级锁和轻量级锁:处理所冲突的结果
重量级锁:做了更多的事情,开销更大
轻量级锁:做的事更少,开销更小 也可以认为通常情况下,悲观锁一般都是重量级锁,乐观锁一般都是轻量级锁
在使用的锁中,如果锁是基于内核的一些功能来实现(比如调用了操作系统的mutex接口)此时一般认为是重量级锁。如果锁是纯用户态实现,此时一般认为这是轻量级锁。
3.挂起等待锁和自旋锁:
挂起等待锁:往往通过等待内核的一些机制来实现,一般较重(重量级锁的一种典型实现)
自旋锁:往往通过用户态代码来实现,一般较轻(轻量级锁的一种典型实现)
4.读写锁和普通互斥锁:
普通互斥锁:只有加锁和解锁两个操作
读写锁:分成三个操作
加读锁ReentrantReadWriteLock.ReadLock:如果代码指示进行读操作就加多操作
加写锁ReentrantReadWriteLock.WriteLock:如果代码中进行了修改操作就加写锁
解锁
5.公平锁和非公平锁
公平锁:多个线程在等待同一把锁的时候,谁先来的就能获取到这个锁(遵守先来后到)
非公平锁:多个线程在等待一把锁的时候,不遵守先来后到(每个等待的线程获取到锁的概率都是均等的),对于操作系统来说,线程之间的调度就是随机的,所以操作系统的mutex这个锁就是非公平锁。
6.可重入锁和不可重入锁
一个线程针对一把锁重复加锁,产生死锁就是不可重入锁,不会死锁就是可重入锁
synchronized总结
1.既是一个乐观锁也是一个悲观锁(根据锁竞争激烈程度自适应)
2.不是读写锁,是一个普通互斥锁
3.既是一个轻量级锁,也是一个重量级锁(根据锁竞争激烈程度自适应)
4.轻量级锁的部分基于自旋锁来实现,重量级锁部分基于挂起等待锁来实现
5.非公平锁
6.可重入锁
synchronized中的锁优化机制
1.锁膨胀/锁升级
体现了synchronized能够自适应的能力
无锁->
偏向锁(首个线程加锁,就会先进入偏向锁的状态,偏向锁不是真的锁只是做了个标记而已)->
自旋锁(又有其他线程加锁产生竞争了,进入了轻量级锁)->
重量级锁(如果竞争进一步加剧,就会进入重量级锁状态)
2.锁粗化
这里的粗细指的是“锁的粒度”,即是加锁代码所涉及的范围,范围越大锁的粒度越粗,范围越小锁的粒度越细。
锁