JUC代码浅析[2]——基于AQS的锁ReentrantLock
ReentrantLock是使用比较普遍的一个可重入锁,它是互斥的,一个锁只能被一个线程占有。它的方法基本都是委托给继承AQS的Sync实现的。其中Sync有两种实现,公平和非公平。Sync使用state(通过AQS暴露的getState和setState方法)保存线程的获取次数。总的策略为state次数为0时可以获得锁。大于0时,如果当前线程已经拥有该锁则可再次获得,否则进入AQS的调度逻辑(<JUC代码浅析——同步器AQS>中介绍)。下面为非公平ReentrantLock的NonfairSync实现,
final void lock() {
if (compareAndSetState(0,
1))
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1);
}
如果state次数为0的话,获得成功并设置当前线程为锁的拥有者。
否则进入AQS调度,acquire(1)方法使用tryAcquire尝试获得,这里重载的tryAcquire调用的是nonfairTryAcquire方法
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
//如果当前重进入数为0,有机会取得锁
if (c == 0) {
//获得成功并设置当前线程为锁的拥有者
if (compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
//如果当前线程已经拥有该锁则可再次获得
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0) // overflow
throw new Error("Maximum
lock count exceeded");
setState(nextc);
return true;
}
//都不满足,则进入AQS队列等待调度
return false;
}
公平ReentrantLock的FairSync实现
protected final boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
//如果当前重进入数为0,有机会取得锁
if (c == 0) {
//如果当前线程是第一个等待者,获得成功并设置当前线程为锁的拥有者
if (isFirst(current) &&
compareAndSetState(0,
acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
//如果当前线程已经拥有该锁则可再次获得
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0)
throw new Error("Maximum
lock count exceeded");
setState(nextc);
return true;
}
//都不满足,则进入AQS队列等待调度
return false;
}
fairSync和NonfairSync的tryRelease方法是同一个,比较简单,就是改变一下state次数,如果需要的话把拥有者线程置为null
protected final boolean tryRelease(int releases) {
int c = getState() - releases;
if (Thread.currentThread() !=
getExclusiveOwnerThread())
throw new IllegalMonitorStateException();
boolean free = false;
if (c == 0) {
free = true;
setExclusiveOwnerThread(null);
}
setState(c);
return free;
}
公平和非公平的区别就在于,尝试进入的时候需要判断当前线程是否是队列的第一个,是第一个才能进入。这样AQS在调度的时候就会阻塞掉很多线程,性能差别就比较大。ReentrantLock只支持互斥模式,没有共享模式
分享到:
相关推荐
AQS是一个抽象的队列同步器,它基于FIFO(先进先出)队列来管理线程的排队和获取共享资源。它是实现Java并发包中锁和其他同步器的基础框架,例如ReentrantLock(可重入锁)、Semaphore(信号量)、CountDownLatch...
在Java中,JUC(java.util.concurrent)包包含了多种并发控制和同步工具,如线程池、锁、并发容器等,这些工具使得开发者能够编写高效、安全、可维护的并发代码。以下将详细讲解其中的一些关键知识点: 1. **线程池...
它提供了实现排他模式(独占式)和共享模式锁的机制,被广泛应用于Java并发包中的ReentrantLock、Semaphore、CountDownLatch等组件中。 首先,AQS是一个抽象类,它的主要特点是使用一个int类型的变量(state)表示...
从JUC中的AQS引入,讲解Java volatile与AQS锁内存可见性
AQS作为Java并发工具包(JUC)中的一个核心抽象类,其设计目的是为了实现各种同步器(如锁、信号量等)。AQS主要通过三个核心组成部分来实现这些同步组件的功能: 1. **State变量及其CAS操作**:AQS维护了一个名为`...
2. **中断支持**:ReentrantLock支持可中断的获取锁,而synchronized不支持。 3. **公平性**:ReentrantLock可配置为公平锁,而synchronized总是非公平的。 4. **锁绑定条件**:ReentrantLock可以通过newCondition()...
juc 的aqs介绍。
这个压缩包文件“个人学习JUC代码笔记总集”显然是一个个人的学习资源,记录了对JUC组件的理解和应用实例,特别适合已经有一定Java基础,想要深入学习并发编程的开发者。 JUC的主要目标是简化并发编程,提高多线程...
JUC中的锁机制包括ReentrantLock(可重入锁)、ReadWriteLock(读写锁)等。ReentrantLock相比synchronized具有更细粒度的控制,支持公平性和非公平性,并提供了tryLock()方法来尝试获取锁,以及lockInterruptibly...
2. **atomic**:这个包包含了一系列原子类,如`AtomicInteger`, `AtomicLong`等,它们提供了在不使用锁的情况下进行原子操作的能力,提高了并发性能。 3. **locks**:此包提供了高级锁定机制,如`ReentrantLock`和`...
AQS通过内部维护一个基于链表的等待队列,有效地管理线程的同步和唤醒,从而实现锁和其他同步原语。 **AQS核心特性:** 1. **资源管理**:AQS定义了两种资源获取方式:独占和共享。独占模式下,只有一个线程能访问...
《AQS和JUC知识点详解》 在Java并发编程领域,AbstractQueuedSynchronizer(AQS)和Java Util Concurrency(JUC)是两个至关重要的概念。它们为开发高效、线程安全的多线程程序提供了强大的工具。本文将深入解析这...
AQS源码分析一、锁的介绍1.1 乐观锁/悲观锁1.2 共享锁/独占锁1.3 公平锁/非公平锁1.4 小结二、AQS框架结构介绍2.1 类图2.2 AQS数据结构三、源码详解3.1 acquire源码详解3.2 release源码详解四、从ReentranLock看公平...
⼀、ReentrantLock重⼊锁 1.1> 概述 1.2> 中断响应 lockInterruptibly() 1.3> 锁申请等待限时 tryLock(long time, TimeUnit unit) 1.4> 公平锁和⾮公平锁 1.5> AQS源码解析 ⼆、Condition重⼊锁的搭配类 三、...
JUC是什么 线程 进程 / 线程 线程状态 wait / sleep 并发 / 并行 Lock 使用Lock锁 可重入锁 公平锁 / 非公平锁 Synchronized / Lock 线程通讯 wait()、notify()和notifyAll() 虚假唤醒 Condition 定制化通信 多线程...
除了`synchronized`之外,Java还提供了更灵活的锁机制——`Lock`接口。`Lock`接口提供了比`synchronized`更强大的锁定机制,并且实现了更加精细的线程控制。 在示例中,使用了`ReentrantLock`类来实现自定义的锁: ...
AQS是Java并发包中的核心抽象类,它是基于FIFO队列的等待锁框架。许多并发工具,如ReentrantLock、Semaphore等,都基于AQS实现。AQS维护了一个内部状态以及一个等待线程的双端队列,通过共享或独占模式来控制资源的...
ReentrantLock Lock 加锁过程源码分析图,AQS 源码分析
Java并发编程是Java开发中的重要领域,而Java并发工具包(Java Concurrency Utility,简称JUC)则是Java标准库提供的一套强大而丰富的工具,它极大地简化了多线程环境下的编程工作。JUC主要包含在`java.util....
### Java并发编程-AQS和JUC实战 #### 一、ReentrantLock 重入锁 **1.1 概述** - **基本介绍**: `ReentrantLock` 是一个实现了 `Lock` 接口的可重入互斥锁,提供比 `synchronized` 更丰富的功能。与 `synchronized...