四、Java并发-ReentrantLock原理(AQS)和synchronized的区别

一、ReentrantLock
重入锁ReentrantLock,就是支持重进入的锁,它表示该锁能够支持一个线程对资源重复加锁。ReentrantLock虽然不像synchronized关键字支持隐式的重进入,调用Lock方法时,获取到锁的线程仍然能再次调用Lock获取锁而不被堵塞。它提供了与synchronized关键字相似的同步,只是在使用时需要显式的获取和释放锁,缺少了便捷性,但拥有了可操作性,可中断获取锁,超时获取锁等特性,该锁还支持获取锁的公平和非公平选择(之后讲解)

(1)ReentrantLock实现了父接口Lock

public class ReentrantLock implements Lock, java.io.Serializable {

ReentrantLock是JDK 1.5之后提供的API层面的互斥锁,需要lock()和unlock()方法配合try/finally语句块来完成,这些方法就来源于父接口Lock,而synchronized是JVM的关键字。

三个主要方法:

public void lock() {
        sync.lock();
    }
public boolean tryLock() {
        return sync.nonfairTryAcquire(1);
    }
public void unlock() {
        sync.release(1);
    }

lock()方法是获取锁,tryLock()是尝试非阻塞的获取锁,unlock()是释放锁,至于为什么调用sync的方法,之后讲解

三个主要功能:
由于ReentrantLock是java.util.concurrent包下提供的一套互斥锁,相比Synchronized,ReentrantLock类提供了一些高级功能,主要有以下3项:

1.等待可中断,持有锁的线程长期不释放的时候,正在等待的线程可以选择放弃等待,这相当于Synchronized来说可以避免出现死锁的情况。通过lock.lockInterruptibly()来实现这个机制。

2.公平锁,多个线程等待同一个锁时,必须按照申请锁的时间顺序获得锁,Synchronized锁非公平锁,ReentrantLock默认的构造函数是创建的非公平锁,可以通过参数true设为公平锁,但公平锁表现的性能不是很好。

公平锁、非公平锁的创建方式:

//创建一个非公平锁,默认是非公平锁
Lock lock = new ReentrantLock();
Lock lock = new ReentrantLock(false);
 
//创建一个公平锁,构造传参true
Lock lock = new ReentrantLock(true);

3.锁绑定多个条件,一个ReentrantLock对象可以同时绑定对个对象。ReenTrantLock提供了一个Condition(条件)类,用来实现分组唤醒需要唤醒的线程们,而不是像synchronized要么随机唤醒一个线程要么唤醒全部线程。

(2)ReentrantLock底层实现
ReentrantLock是使用组合自定义同步器(AQS)来实现锁的获取和释放,下面就是ReentrantLock的AQS源码

 private final Sync sync;
 
 abstract static class Sync extends AbstractQueuedSynchronizer {//继承了AQS类

所以上面ReentrantLock的三个主要方法都是调用的AQS其中的方法

(3)AQS是什么?
队列同步器AbstractQueuedSynchronizer(简称同步器),是用来构建锁或其他同步组件的基础框架,通过内置的FIFO队列来完成获取线程的排队工作AQS主要利用硬件原语指令(CAS compare-and-swap),来实现轻量级多线程同步机制,并且不会引起CPU上文切换和调度,同时提供内存可见性和原子化更新保证(线程安全的三要素:原子性、可见性、顺序性)。

二、两者的区别
(1)synchronized 是 JVM 实现的,而 ReentrantLock 是 JDK 实现的
(2)synchronized 中的锁是非公平的,ReentrantLock 默认情况下也是非公平的,但是也可以是公平的。
(3)synchronized比较简单,ReentrantLock需要lock()和unlock()来实现,较为复杂

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值