在java的并发包中,提供了各种各样的并发锁(ReentrantLock,CountDownLatch,Semaphore),这些锁的实现都是继承AQS(AbstractQuerySynchronizer)。
AbstractQuerySynchronizer是一个抽象类,他继承了AbstractOwnableSynchronizer和Seriallizade两个类。
其中AbstractOwnableSynchronizer主要包含一个Thread成员,代表获取锁的独有线程。
AQS有个内部类Node,包含一个线程,每个线程来请求锁的时候,封装成一个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; final boolean isShared() { return nextWaiter == SHARED; } final Node predecessor() throws NullPointerException { Node p = prev; if (p == null) throw new NullPointerException(); else return p; } }
AQS是把所有竞争锁的线程构成一个双向链表,采用成员变量
private volatile int state;
作为共享变量,由三个方法对该变量进行操作和获取
protected final int getState() { return state; }
protected final void setState(int newState) { state = newState; }
protected final boolean compareAndSetState(int expect, int update) { // See below for intrinsics setup to support this return unsafe.compareAndSwapInt(this, stateOffset, expect, update); }其中compareAndsetState方法是使用CAS原理,不明白可以先去看看CAS原理,保证更新内存变量的原子性。
下面主要介绍一下AQS的主要方法
protected boolean tryAcquire(int arg) { throw new UnsupportedOperationException(); }
protected boolean tryRelease(int arg) { throw new UnsupportedOperationException(); }protected int tryAcquireShared(int arg) { throw new UnsupportedOperationException(); }protected boolean tryReleaseShared(int arg) { throw new UnsupportedOperationException(); }
这四个方法是AQS的组要方法了,具体实现锁的时候就需要实现其中两个方法。从方法名称知道是一类独占锁实现,一类是共享锁实现。
对于多个线程获取锁时候线程的阻塞等待,AQS已经帮我们实现完成。
注:锁有公平锁和非公平锁的区别,这个主要是有具体的锁实现类来完成。公平锁是指所有竞争锁的线程来了以后一次排在队列后面。
非公平锁是进来以后先去获取资源stat,如果获取成功,得到锁,否则加入队列。
未完待续......