同步队列

本文深入分析了Java的AQS同步队列实现,详细介绍了同步队列的节点信息、首尾节点设置、独占式和共享式获取与释放锁的流程。AQS通过内部FIFO队列管理同步状态,当线程获取锁失败时,线程信息会被构造成节点加入队列尾部,并在适当时候唤醒并获取同步状态。
摘要由CSDN通过智能技术生成

 

一  AQS同步队列实现分析

AQS是一个

1  同步队列

AQS是通过一个内部的FIFO的同步队列来管理同步状态,当线程获取锁失败的时候,当前想线程以及当前线程的状态等信息,会被构造成一个节点加入到同步队列的尾部,然后阻塞当前线程。那么这个节点保存哪些信息呢?

当前线程的引用、等待状态以及当前节点的前驱节点和后继节点。

同步器中存在两种引用:指向首节点的引用和指向尾节点的引用.

首节点是成功获取同步状态的节点,当首节点释放同步状态的时候,将会唤醒后继节点,当后继节点成功获取同步状态以后会将自己设置为首节点。关于首节点和尾节点的设置有一下两点需要说下:

a.首节点是成功获取同步状态的节点,因为只有一个线程可以成功获取同步状态,因此设置首节点不需要CAS设置。

b.一般情况下,会有多个获取锁失败,而获取锁失败的节点会被设置为尾节点,这里线程是通过CAS设置尾节点的,同一时刻必须保证只能一个线程加入到队列尾部,将尾节点的引用指向当前线程的节点.当成功设置为尾节点以后,只有正式设置成功以后,该节点才能与之前的尾节点建立连接。

 

2 独占式获取锁和释放锁

关于独占式获取锁,.首先调用acquire(int arg)方法。

 public final void acquire(int arg) {
        if (!tryAcquire(arg) &&
            acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
            selfInterrupt();
    }

线程调用tryAcquire方法去获取同步状态,tryAcquire方法是需要子类自己实现的,当获取同步状态失败以后,调用addWaiter(Node.EXCLUSIVE)方法将当前线程创建为节点加入到队列尾部

 /**
     * Creates and enqueues node for current thread and given mode.
     *
     * @param mode Node.EXCLUSIVE for exclusive, Node.SHARED for shared
     * @return the new node
     */
    private Node addWaiter(Node mode) {
        Node node = new Node(Thread.currentThread(), mode);
        // Try the fast path of enq; backup to full enq on failure
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值