AbstractQueuedSynchronizer(AQS) 同步器 是JAVA5 实现锁关建。利用同步器将所得语义(Semantic) 实现, 然后在自定义锁的实现中聚合AQS同步器。这里推荐一篇非常好的关于AQS的文章:
http://ifeve.com/introduce-abstractqueuedsynchronizer/
下面是自定锁的一个实现,其实就是Semphore, 令牌数为2 的例子。
package com.bill.mq.common;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
/**
* 一个锁, 在同一时间,只能有2个线程能够并行访问,超过限制的其他进程进入阻塞状态。<br/>
* 定义一个资源初始状态为2, 一个进程进入获取,那么减少1, 一个进程释放,那么加1。<br/>
* 资源状态的正确范围在【0,1,2】三个之间。<br/>
* 当为0时,代表再有新的线程对资源进行获取时,只能进入阻塞状态。<br/>
* 注意在任何时候进行状态变更的时候,均要以CAS作为原子性保障。 <br/>
* 由于资源的数量多以1个, 同时可以有两个线程占用资源,需要实现tryAcquireShared 和 tryReleaseShared 方法。
*
*/
public class MyTwinsLock implements Lock {
private final Sync sync = new Sync(2);
private static final class Sync extends AbstractQueuedSynchronizer {
Sync(int count) {
if (count < 0) {
throw new IllegalArgumentException("count must be large than zero");
}
setState(count);
}
@Override
protected int tryAcquireShared(int reduceCount) {
for (;;) {
int current = getState();
int newCount = current - reduceCount;
if (newCount < 0 || compareAndSetState(current, newCount)) {
return newCount;
}
}
}
@Override
protected boolean tryReleaseShared(int returnCount) {
for (;;) {
int current = getState();
int newCount = current + returnCount;
if (compareAndSetState(current, newCount)) {
return true;
}
}
}
}
@Override
public void lock() {
sync.acquireShared(1);
}
@Override
public void lockInterruptibly() throws InterruptedException {
sync.acquireSharedInterruptibly(1);
}
@Override
public boolean tryLock() {
return sync.tryAcquireShared(1) >= 0;
}
@Override
public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
return sync.tryAcquireSharedNanos(1, unit.toNanos(time));
}
@Override
public void unlock() {
sync.releaseShared(1);
}
@Override
public Condition newCondition() {
return null;
}
}