AQS的实现思想

AQS:AbstractQueuedSynchronizer,抽象队列同步器。前面已经解析了部分AQS的源码,这里只是简单讲述下AQS的实现思想。

同步状态(state)的管理

    private volatile int state;

    protected final int getState() {
        return state;
    }

    protected final void setState(int newState) {
        state = newState;
    }

 AQS很巧妙的用到了volatile+compareAndSetState对同步状态的管理。【关键字synchronized 和volatile】中提到,volatile能够保证不同线程对共享变量操作的可见性,并且能够保证简单操作(set/get操作,但是i++这类的不行)原子性,但是不能保证共享变量在多个线程执行写操作时的线程安全。而在AQS中,所有多线程操作state的时候都是通过compareAndSetState实现的。

Node

    static final class Node {
        /** 两种模式 */
        //共享模式
        static final Node SHARED = new Node();
        //独占模式
        static final Node EXCLUSIVE = null;
 
        /**waitstatus值的含义 */
        //节点设置为取消状态
        static final int CANCELLED =  1;
        //后续节点需要被唤醒
        static final int SIGNAL    = -1;
        //节点处于等待队列中,等待队列中的节点进入同步队列,状态会设置成0
        static final int CONDITION = -2;
        //共享可以传递给其他节点
        static final int PROPAGATE = -3;
 
        //状态字段,除了上面四种状态,还有一个0,表示默认状态
        volatile int waitStatus;
 
        //当前节点的前一节点
        volatile Node prev;
 
        //当前节点的后一节点
        volatile Node next;
 
        //当前节点对应的线程
        volatile Thread thread;
 
        //condition队列中的后一节点
        Node nextWaiter;
 
        //共享模式下等待,返回true
        final boolean isShared() {
            return nextWaiter == SHARED;
        }
        
        //返回当前节点的前一节点,为null则抛出异常
        final Node predecessor() throws NullPointerException {
            Node p = prev;
            if (p == null)
                throw new NullPointerException();
            else
                return p;
        }
 
        Node() {    // Used to establish initial head or SHARED marker
        }
 
        Node(Thread thread, Node mode) {     // Used by addWaiter
            this.nextWaiter = mode;
            this.thread = thread;
        }
 
        Node(Thread thread, int waitStatus) { // Used by Condition
            this.waitStatus = waitStatus;
            this.thread = thread;
        }
    }

Node中有CLH同步队列和Condition等待队列的指向属性,所以Node在CLH同步队列和Condition等待队列上新增/删除操作都非常方便;Node中的thread标识节点对应的线程,并且线程的属性也存在Node中,这样对线程的操作就直接转换成对Node的操作,这样AQS只要维护好同步队列和等待队列即能保障对线程的管理。

CLH同步队列

 新节点加入同步队列,通过CAS操作,将节点拼接到tail节点后,成为新的尾节点;节点从同步队列中删除时,只需要将其设置成head节点,并确定好next节点。

Condition等待队列

 添加节点到等待队列中,会将原来lastWaiter的nextWaiter指向新增节点,然后将新增节点设置成lastWaiter;从等待队列中删除节点,将节点的nextWaiter置为null,(如果存在)删除节点前一节点的nextWaiter重新指向到删除节点的后一节点。

线程阻塞与唤醒

AQS中线程的使用与唤醒用的是LockSupport类中park/unpark方法,park/unpark可以阻塞或者唤醒指定的线程。

源码解析:

【ReentrantLock源码解析】

【ReentrantReadWriteLock源码】

【AQS中ConditionObject(Condition接口实现)源码解析】

 

 

如果有写的不对的地方,请大家多多批评指正,非常感谢!

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值