ReentrantLock与AQS源码分析

       

目录

ReentrantLock 锁的特点

ReentrantLock核心代码讲解

AQS核心代码: 


 

      本文主要从源码的角度分析下java中的Lock锁以及他的底层依赖AQS,在多线程编程中我们一定会用到锁,java提供了JUC包来更好的并发编程,,关于JUC包的介绍可以参看之前的文章。

主要分为一下几个部分:

      1.ReentrantLock 锁的特点,

      2.ReentrantLock核心代码讲解

      3.AQS 的核心代码讲解

ReentrantLock 锁的特点

ReentrantLock是Lock接口的具体实现,lock锁相对于synchronized是轻量级锁,是api级别的,synchronized是JVM级别的,Lock的具体特点如下:

1)使用方面需要显示的获取锁,并需要主动释放锁。

2)可中断,可重入。

3)支持公平锁和非公平锁。

ReentrantLock核心代码讲解

总体介绍:这里只简单的介绍基本的构造函数、核心变量和核心方法,不会把所有代码和方法列出。

1)核心变量:有一个核心内部类变量private final Sync sync,是实现了同步线程队列AQS。同时他有两个实现类NonfairSync(非公平锁)和FairSync(公平锁)。

Sync类源码:

              watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5a-G5bqm5q-U5L6L,size_20,color_FFFFFF,t_70,g_se,x_16

 

NonfairSync(非公平锁)源码)

               watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5a-G5bqm5q-U5L6L,size_20,color_FFFFFF,t_70,g_se,x_16

 FairSync(公平锁)

              watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5a-G5bqm5q-U5L6L,size_20,color_FFFFFF,t_70,g_se,x_16

 

2)构造函数:ReentrantLock有两个构造函数,一个无惨构造函数ReentrantLock(),默认是非公平锁实现,一个有参构造函数ReentrantLock(boolean fair),参数fair代表的是否是公平锁。一般情况下非公平锁要比公平锁效率高,因为减少了队列中唤醒线程时的线程切换,所以默认是非公平锁。

                  watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5a-G5bqm5q-U5L6L,size_20,color_FFFFFF,t_70,g_se,x_16

3)核心方法:

        获取锁的方法:lock()、tryLock()和tryLock(long timeout, TimeUnit unit)三个方法

,lock()是调用的sync.lock(),也就是根据ReentrantLock对象是公平锁还是非公平锁来获取锁,tryLock直接是非公平锁逻辑,调的是sync的nonfairTryAcquire()方法,而tryLock(long timeout, TimeUnit unit)是在超时间内获取到锁返回true,否则是false,它获取的是公平还是非公平锁也是由ReentrantLock具体对象决定。

                    watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5a-G5bqm5q-U5L6L,size_20,color_FFFFFF,t_70,g_se,x_16

                  watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5a-G5bqm5q-U5L6L,size_20,color_FFFFFF,t_70,g_se,x_16

                   watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5a-G5bqm5q-U5L6L,size_20,color_FFFFFF,t_70,g_se,x_16 

释放锁的方法:unlock(),他直接调用的sync.release(1)。

             watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5a-G5bqm5q-U5L6L,size_20,color_FFFFFF,t_70,g_se,x_16

获取线程同步条件对象:newCondition()方法是返回一个Condition对象,用于线程间协同通信。

             watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5a-G5bqm5q-U5L6L,size_20,color_FFFFFF,t_70,g_se,x_16

AQS源码分析

        AQS是 AbstractQueuedSynchronizer的缩写,是一个abstract 类,通过上边ReentrantLock的分析,可以看出ReentrantLock底层就是AbstractQueuedSynchronizer,是通过Sync继承了AbstractQueuedSynchronizer,重写了获取和释放锁的具体逻辑。

   那么AQS基本原理很明确,就是解决锁状态问题,解决未获取到锁的线程阻塞问题、以及多线程间的同步问题,所以AQS具体结构:

  1. Abstract : 是一个抽象类,因为不具体上锁,所以通过模版设计模式暴露上锁逻辑,有子类实现tryAcquire()和tryRelease()。
  2. Queue:线程阻塞队列,完成抢不到锁的队列排队。
  3. Synchronizer:同步
  4. CAS+state:完成多线程抢锁逻辑

AQS核心代码: 

核心方法:

       获取锁的方法acquire(int arg) ,具体逻辑是先通过CAS获取锁,如果成功返回成功,失败则如阻塞队列:

           watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5a-G5bqm5q-U5L6L,size_20,color_FFFFFF,t_70,g_se,x_16

            watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5a-G5bqm5q-U5L6L,size_20,color_FFFFFF,t_70,g_se,x_16

 释放锁:release(int arg)释放锁,先判断释放锁是否成功,成功了唤醒队列里的等待线程。

          watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5a-G5bqm5q-U5L6L,size_20,color_FFFFFF,t_70,g_se,x_16

          watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5a-G5bqm5q-U5L6L,size_20,color_FFFFFF,t_70,g_se,x_16 

 

 

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

密度比例

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值