Java悲观锁与重入锁ReentrantLock的区别

java锁一共分为3种锁  乐观锁、悲观锁、自旋锁

今天主要讲下悲观锁,即认为写多,遇到并发写的可能性高,每次去拿数据的时候都认为别人
会修改,所以每次在读写数据的时候都会上锁。悲观锁有一个关键字是Synchronized,AQS框架下的锁则是先尝试cas乐观锁去获取锁,获取不到,才会转换为悲观锁。

Synchronized作用范围

1、作用于方法时,锁住的是对象实例(this)

2、作用于静态方法时,锁住的Class实例,又因为Class的相关数据存储在永久带PermGen(jdk1.8 则是 metaspace),永久带是全局共享的,因此静态方法锁相当于类的一个全局锁,会锁所有调用该方法的线程。

3、synchronized作用于一个对象的实例时,锁住的是所有以该对象为锁的代码块,他有多个队列当多个线程一起访问某个对象监视器的时候,对象监视器会将这些线程存储到不同的容器中。

Synchronized核心组件

1)wait set:哪些调用wait的方法被阻塞的方法存在这里。

2)Contention List:竞争对列,所有请求锁的线程首先会存放到这个竞争队列里;

3)Entry List:Contention List 中那些有资格成为候选资源的线程移动到EntryList中;

4)OnDeck:任意时刻,最多只有一个线程正在竞争锁资源,该线程被成为OnDeck;

5)Owner:当前已经获取到的锁资源的线程为Owner;

6)!Owner:当前释放的线程。

下面说下重入锁(ReentrantLock)

ReentrantLock继承接口 Lock 并实现了接口中定义的方法,他是一种可重入锁,除了能完成 synchronized 所能完成的所有工作,还提供了诸如可响应中断锁、可轮询锁请求、定时锁等避免多线程死锁的方法

非公平锁和公平锁

RenntrantLock区分公平锁和非公平锁 在创建实例的时候有一个默认的参数true,false   false代表非公平锁,true代表公平锁

表达方式反之是公平锁默认是非公平锁

非公平锁

JVM 按随机、就近原则分配锁的机制则称为不公平锁,ReentrantLock 在构造函数中提供了是否公平锁的初始化方式,默认为非公平锁。非公平锁实际执行的效率要远远超出公平锁,除非程序有特殊需要,否则最常用非公平锁的分配机制。

公平锁

公平锁指的是锁的分配机制是公平的,通常先对锁提出获取请求的线程会先被分配到锁,ReentrantLock 在构造函数中提供了是否公平锁的初始化方式来定义公平锁

ReentrantLock 与 synchronized
1. ReentrantLock 通过方法 lock()与 unlock()来进行加锁与解锁操作,与 synchronized 会被 JVM 自动解锁机制不同ReentrantLock 加锁后需要手动进行解锁。为了避免程序出现异常而无法正常解锁的情况,使用 ReentrantLock 必须在 finally 控制块中进行解锁操作。
2. ReentrantLock 相比 synchronized 的优势是可中断、公平锁、多个锁。这种情况下需要使用 ReentrantLock

注ReentrantLock可重复加多个锁!!!

你可能感兴趣的:(java基础)