J.U.C-AQS框架简介

AQS 简介

AbstractQueuedSynchronizer抽象队列同步器,简称为AQS,可用于构建阻塞锁或者其他相关同步器的基础框,是Java并发包的基础工具类。通过AQS这个框架可以对同步状态原子性管理、线程的阻塞和解除阻塞、队列的管理进行统一管理。
AQS是抽象类,并不能直接实例化,当需要使用AQS的时候需要继承AQS抽象类并且重写指定的方法,这些重写方法包括线程获取资源和释放资源的方式(如ReentractLock通过分别重写线程获取和释放资源的方式实现了公平锁非公平锁),同时子类还需要负责共享变量state的维护,如当state为0时表示该锁没有被占,大于0时候代表该锁被一个或多个线程占领(重入锁),而队列的维护(获取资源失败入队、线程唤醒、线程的状态等)不需要我们考虑,AQS已经帮我们实现好了。AQS的这种设计模式采用的正是模板方法模式。

AQS的内部结构

AQS内部数据结构为一个双向链表一个单向链表双链表为同步队列,队列中的每个节点对应一个Node内部类,AQS通过控制链表的节点而达到阻塞、同步的目的,单链表为条件队列,可以把同步队列和条件队列理解成储存等待状态的线程的队列,但是条件队列中的线程并不能直接去获取资源,而要先从条件队列转到同步队列中排队获取,同步队列的唤醒结果是线程去尝试获取锁,而条件队列的唤醒结果是把线程从条件队列移到同步队列中,一个线程要么是在同步队列中,要么是在条件队列中,不可能同时存在这两个队列里面。
在这里插入图片描述

从下面例子就可以看到对两个队列的操作, 从而达到对线程的交互.

ReentrantLock和Condition组件搭配使用:

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

@Slf4j
public class LockExample6 {

    public static void main(String[] args) {
        ReentrantLock reentrantLock = new ReentrantLock();
        Condition condition = reentrantLock.newCondition();

        new Thread(() -> {
            try {
                reentrantLock.lock();   // 此时被加入到了AQS等待序列中
                log.info("wait signal"); // 1
                condition.await();  // 又被AQS移除了(await操作释放了锁) 进入了Condition的等待队列中 
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            log.info("get signal"); // 4 获得信号
            reentrantLock.unlock();
        }).start();

        new Thread(() -> {
            reentrantLock.lock();  // 获得锁 进入AQS等待序列中
            log.info("get lock"); // 2
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            condition.signalAll(); // 发送信号唤醒所有等待的线程 将Condition等待队列中的线程1节点的 取出并加入到AQS等待队列中
            log.info("send signal ~ "); // 3
            reentrantLock.unlock();
        }).start();
    }
}
发布了250 篇原创文章 · 获赞 417 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/qq_33709508/article/details/105469145