前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >浅析AQS

浅析AQS

作者头像
一个架构师
发布2022-06-20 20:03:43
1770
发布2022-06-20 20:03:43
举报
文章被收录于专栏:从码农的全世界路过

AQS是AbstractQueuedSynchronizer类的简写, 它提供了一套基础的同步框架, 可以根据自定义扩展. AQS细节较多, 今天只从宏观的角度, 看下它是怎样设计实现的.

核心设计

首先, AQS是基于以下两个核心做的设计:

1.双向队列(CLH队列)

CLH队列全称是(Craig, Landin, andHagersten) lock queue, 用来存储被阻塞的线程信息.

2.资源状态state

在独占锁的场景下, 可以理解为资源占有的标识位; 在共享锁的情况下, 可以作为资源数量理解.

独占锁与共享锁

AQS中提供了两套锁机制: 共享锁与独占锁

共享锁:

可以有多个线程同时执行, 线程执行个数也会受到state限制, 如Semaphore,CountDownLatch等等

独占锁:

当前只有一个线程能够运行, 如ReentrantLock;

独占锁又分为公平锁(FairSync)和非公平锁(NonfairSync)

公平锁: 所有线程严格按照FIFO占有锁.

代码语言:javascript
复制
final void lock() {
    acquire(1);
}

非公平锁: 每个线程不管是否有其他线程等待, 都会先尝试抢占锁, 抢占失败再去CLH队列中等待锁资源释放.

代码语言:javascript
复制
    final void lock() {
        if (compareAndSetState(0, 1))
            setExclusiveOwnerThread(Thread.currentThread());
        else
            acquire(1);
    }

CAS操作

AQS在获得资源状态state, 以及添加阻塞线程到CLH队尾时都是使用CAS操作解决线程间资源抢占问题的.

1. 获取资源:

代码语言:javascript
复制
compareAndSetState(0, 1)

2. 添加线程到CLH队尾

Node中封装线程及锁独占或共享标识

代码语言:javascript
复制
private Node addWaiter(Node mode) {
    Node node = new Node(Thread.currentThread(), mode);
    // Try the fast path of enq; backup to full enq on failure
    Node pred = tail;
    if (pred != null) {
        node.prev = pred;
        if (compareAndSetTail(pred, node)) {
            pred.next = node;
            return node;
        }
    }
    enq(node);
    return node;
}

线程阻塞及唤醒

在AQS中, 当线程抢占资源失败时, 会调用unsafe.park()方法阻塞线程;

当其他线程释放资源时, 也会调用unsafe.unpark()唤醒线程;

模板模式

为方便扩展应用, AQS内部已经实现了CLH队列, 线程的阻塞唤醒等复杂逻辑, 我们只需要根据需要完成独占模式或共享模式下的状态同步方法即可.

tryAcquire: 独占模式下获取同步资源

tryRelease: 独占模式下释放同步资源

isHeldExclusively: 独占模式下查看当前线程是否获取同步资源

tryAcquireShared: 共享模式下获取同步资源

tryReleaseShared: 共享模式下释放同步资源

AQS处理流程

有了上述各实现功能, 我们可以猜想的到AQS的处理流程了, 当然实际情况会复杂的多.

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-07-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 从码农的全世界路过 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档