聊聊Java的锁

一. 悲观锁、乐观锁

1、悲观锁认为共享资源并发操作一定会出现问题,使用synchronized关键字或者lock接口特性加锁;

2、乐观锁认为不加锁给并发操作带来性能提升,常采用CAS(Compare比较 And Swap交换)自旋锁;典例就是并发原子类,通过CAS自旋来更新值

二. 公平锁、非公平锁

1、公平锁指多个线程按照申请锁顺序依次获取锁;

2、非公平锁不考虑排队等待问题,直接尝试获取,获取不到自动队尾等待;(随机就近原则)
synchronized是非公平锁,ReentrantLock默认的lock是非公平锁;

三. 独占锁、共享锁

独占锁是一种悲观锁策略,每次只能一个线程持有锁
synchronized,ReentrantLock都是独占锁, 但对于ReadWriteLock接口而言,读是共享,写是独享,在lock的实现中通过AQS(抽象队列同步器)实现;

四. 可重入锁(递归锁)

指的是同一个线程,外层函数获得锁后,内层函数仍然有获取该锁的代码(即内层函数自动获取锁),但不受影响;
synchronized,ReentrantLock都是可重入锁;最大好处能避免一定程度的死锁;

五. 自旋锁

如果持有锁线程短时间内释放锁,那么等待竞争锁的线程就不需要做内核态和用户态之间的切换,进入阻塞挂起状态,
只需要等一等(自旋)一会等持有锁的线程释放后立即获取,避免了用户线程和内核的切换消耗,但是占用cpu;
底层采用CAS来保证原子性,自旋锁获取锁时不会阻塞,而是通过不断的while循环的方法尝试获取锁; jdk1.7后:去掉参数,由jvm控制;java.util.concurrent包下几乎都是利用自旋锁;

六. 分段锁

分段锁是一种思想,并非实际锁。典型的ConcurrentHashMap.

七. 偏向锁、轻量级锁、重量级锁

锁的状态四种:无锁状态、偏向锁、轻量级锁、重量级锁【锁的状态是通过对象监视器在对象头中字段来表明的】
锁的状态只有升级,没有降级
偏向锁: 一段代码一直被同一个线程访问,那么该线程就会自动获取锁 轻量级锁: 当锁是偏向锁的时候,被另一个线程访问,偏向锁就会升级为轻量级锁,其他线程会通过自旋方式尝试获取锁,不会阻塞,提高性能 重量级锁: 当轻量级锁自旋超过一定次数,或者有三个线程来访问时,轻量级锁膨胀为重量级. 重量级锁除了拥有锁的线程以外的线程都阻塞,防止cpu空转 偏向锁,轻量级锁都是乐观锁,重量级锁时悲观锁

 

posted @ 2021-07-16 21:56  Sherlock先生  阅读(66)  评论(0编辑  收藏  举报