目录
4.1 ReentrantLock 与 synchronized 区别
1、锁的分类
1.1 可重入锁、不可重入锁
1.1.1 定义
重入:当前线程获取到A锁,在获取之后尝试再次获取A锁是可以直接拿到的。
不可重入:当前线程获取到A锁,在获取之后尝试再次获取A锁,无法获取到的,因为A锁被当前线程占用着,需要等待自己释放锁再获取锁。
Java中提供的synchronized,ReentrantLock,ReentrantReadWriteLock都是可重入锁。
1.2 乐观锁、悲观锁
1.2.1 定义
乐观锁:乐观锁:顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。
在 Java中 java.util.concurrent.atomic 包下面的原子变量类就是使用了乐观锁的一种实现方式 CAS 实现的。
悲观锁:总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁,就是在做操作之前先上锁。
Java中提供的synchronized,ReentrantLock,ReentrantReadWriteLock都是悲观锁。
1.3 公平锁、非公平锁
1.3.1 定义
公平锁:当有线程占用锁时,并有线程在排队时,直接排在线程后面,排序等待。
非公平锁:线程一进来就会尝试获取一波锁资源,如果获取失败,再去排队等待。
Java中提供的synchronized只能是非公平锁。
Java中提供的ReentrantLock,ReentrantReadWriteLock可以实现公平锁和非公平锁
1.4 互斥锁、共享锁
1.4.1 定义
互斥锁:同一时间点,只会有一个线程持有者当前互斥锁。
Java中提供的synchronized、ReentrantLock是互斥锁。
共享锁:同一时间点,当前共享锁可以被多个线程同时持有。
Java中提供的ReentrantReadWriteLock,有互斥锁也有共享锁。(读锁是共享锁)
2、synchronized
2.1 类锁,对象锁
synchronized 是基于对象实现的,一般使用同步代码块或同步方法的方式。
类锁:在static修饰的类或方法上使用synchronized 修饰时,使用当前类的class作为锁对象。
对象锁:修饰非static 修饰的类或方法时,synchrozined会以当前实例对象作为锁对象。
public class MiTest {
public static void main(String[] args) {
// 锁的是,当前Test.class
Test.a();
Test test = new Test();
// 锁的是new出来的test对象
test.b();
}
}
class Test{
public static synchronized void a(){
System.out.println("1111");
}
public synchronized void b(){
System.out.println("2222");
}
}
2.2 synchronized 优化
锁消除:在synchronized修饰的代码中,如果不存在操作临界资源的情况,会触发锁消除,你即便写了synchronized,他也不会触发。
public synchronized void method(){
// 没有操作临界资源
// 此时这个方法的synchronized你可以认为木有~~
}
锁膨胀:如果在一个循环中,频繁的获取和释放做资源,这样带来的消耗很大,锁膨胀就是将锁的范围扩大,避免频繁的竞争和获取锁资源带来不必要的消耗。
public void method(){
for(int i = 0;i < 999999;i++){
synchronized(对象){
}
}
// 上面的代码会触发锁膨胀,变成下面这种形式
synchronized(对象){
for(int i = 0;i < 999999;i++){
}
}
}
锁升级:ReentrantLock的实现,是先基于乐观锁的CAS尝试获取锁资源,如果拿不到锁资源,才会挂起线程。synchronized在JDK1.6之前,完全就是获取不到锁,立即挂起当前线程,所以synchronized性能比较差。
- 无锁、匿名偏向:当前对象没有作为锁存在。
- 偏向锁:如果当前锁资源,只有一个线程在频繁的获取和释放,那么这个线程过来,只需要判断,当前指向的线程是否是当前线程 。
-
如果是,直接拿着锁资源走。
-
如果当前线程不是我,基于CAS的方式,尝试将偏向锁指向当前线程。如果获取不到,触发锁升级,升级为轻量级锁。(偏向锁状态出现了锁竞争的情况)
-
-