乐观锁 悲观锁(锁冲突概率的角度上)
乐观锁:预测锁竞争不是很激烈(做的工作相对更少),悲观锁:预测锁竞争会很激烈(做的工作可能就会更多一点),出发点不同,背后的工作是截然不同的,疫情放开,小明认为应该屯粮屯药,小红认为没啥事,该来的总会来,小红处于一个对这个事情乐观的状态,小明处于对这个事悲观的状态,悲观和乐观的唯一区分,主要就是看预测锁竞争激烈程度的结论,如果你接下来的工作都是围绕着锁竞争不激烈展开的,那就是一个乐观锁,如果围绕激烈展开的,那么就是悲观锁
轻量级锁 重量级锁(锁开销的角度上)
轻量级锁加锁解锁开销比较小,效率更高,重量级锁加锁解锁开销比较大,效率更低,多数情况下,乐观锁也是一个轻量级锁,但是不能完全保证,也可能开销比较大是重量级锁。悲观锁也是一个重量级锁,也可能是轻量级。
自旋锁 挂起等待锁
自旋锁是一种典型的轻量级锁,自旋可以理解为自我旋转,自我循环,就是自己在这里不停的循环,直到目的达成,消耗了大量精力,占用了大量的系统资源,但是第一时间可以获取到锁被释放,有更大的概率获取到锁,加锁速度比较快。我和朋友去逛街,朋友说要五分钟准备好,于是,我就在楼下等,每个一分钟给朋友发消息询问情况。
挂起等待锁是一种典型的重量级锁就是我和朋友商量去逛街,她说要过会才可以去,那我就在旁边奶茶店喝奶茶,把cpu省下来去干别的,等到她想起我时,再去联系我,把我唤醒。
互斥锁 读写锁
互斥锁就是像synchronized这样的锁,提供加锁和解锁两个操作,如果一个线程加锁了,另一个线程也尝试加锁,就会阻塞等待。
读写锁就是提供了三种操作,针对读加锁,针对写加锁,解锁,多线程针对同一个变量并发读。这时候没有线程安全问题,也不需要加锁,读写锁就是针对这个情况所采取的特殊处理,读锁和读锁之间,没有互斥,写锁和写锁,写锁和读锁之间存在互斥,当前代码中,如果只是读操作,加读锁就可以,如果有写操作,加写锁。假如如果当前线程都去读,去加读锁,这些锁之间没有锁竞争,也没有线程安全,加锁可以让线程又快又准。
公平锁 非公平锁
公平锁:排队,排到前面的先获取锁
非公平锁:雨露均沾
操作系统和java synchronized原生都是“非公平锁”,操作系统这里的针对加锁的控制,本身就依赖于线程调度顺序的,这个调度顺序是随机的,不会考虑到这个线程等待锁多久了,要想实现公平锁,就得再这个基础上,能够引入额外的东西(引入一个队列,让这些加锁的线程去排队),这个时候就可以实现公平锁。
可重入锁 不可重入锁
不可重入锁:一个线程针对一把锁,连续加锁两次,出现死锁。
可重入锁:一个线程针对一把锁,连续加锁多次都不会出现死锁
1.synchronized既是一个悲观锁,也是一个乐观锁,synchronized默认是一个乐观锁,但是如果发现当前锁竞争比较激烈,就会转换为悲观锁,2.既是轻量级也是重量级锁,默认是轻量级锁,如果发现当前锁竞争比较激烈,就会转换为重量级锁3.synchronized这里的轻量级锁是基于自旋锁的方式实现的,synchronized这里的重量级锁,是基于挂起等待锁的方式实现的。4.synchronized不是读写锁。5.synchronized是公平锁。6.synchronized是可重入锁。