一、ReentrantLock的基本使用示例
ReentrantLock是AbstractQueuedSynchronizer的一个子类
public class ClassLayOutTest {
static ReentrantLock reentrantLock = new ReentrantLock();
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(9);
for (int i = 0; i < 20; i++) {
executorService.execute(ClassLayOutTest::reentrantLockDemo);
}
}
public static void reentrantLockDemo() {
reentrantLock.lock();
try {
System.out.println(Thread.currentThread().getName() + ": 获取到锁! -->" + System.currentTimeMillis()/1000);
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
reentrantLock.unlock();
}
}
}
二、简要概述
AQS就是AbstractQueuedSynchronizer抽象类,AQS其实就是JUC包下的一个基类,JUC下的很多内容都是基于AQS实现了部分功能,比如ReentrantLock,ThreadPoolExecutor,阻塞队列,CountDownLatch,Semaphore,CyclicBarrier等等都是基于AQS实现。
首先AQS中提供了一个由volatile修饰,并且采用CAS方式修改的int类型的state变量。
其次AQS中维护了一个双向链表,有head,有tail,并且每个节点都是Node对象
AQS类中核心属性:state(为0的时候,资源没有都锁定)、head、tail
node的重要的几个属性:waitStatus、thread、pre、next四个属性。
主要示例如下:
线程多并发的时候,如果线程抢占不到锁,就会把抢占不到锁的线程包装成一个Node实例,然后放入AQS的双向队列中。Node类的核心代码如下:
static final class Node {
static final Node SHARED = new Node();
static final Node EXCLUSIVE = null;
static final int CANCELLED = 1;
static final int SIGNAL = -1;
static final int CONDITION = -2;
static final int PROPAGATE = -3;
volatile int waitStatus;
volatile Node prev;
volatile Node next;
volatile Thread thread;
Node nextWaiter;
}