定义
AbstractQueuedSynchronizer为实现依赖于先进先出 (FIFO) 等待队列的阻塞锁定和相关同步器(ReentrantLock、Semaphore,CountDownLatch等等)提供一个框架。此类的设计目标是成为依靠单个原子 int 值来表示状态的大多数同步器的一个有用基础。子类必须定义更改此状态的受保护方法,并定义哪种状态对于此对象意味着被获取或被释放。假定这些条件之后,此类中的其他方法就可以实现所有排队和阻塞机制。但只是为了获得同步而只追踪使用 getState()、setState(int) 和 compareAndSetState(int, int) 方法来操作以原子方式更新的 int 值。
AQS中模板设计模式
要实现同步方法的类一般通过继承AbstractQueuedSynchronizer类,并重写其中的抽象方法来实现同步方式,AQS基于模板方法模式设计,定义了同步方法的主要流程、骨架,留出一分部可变的过程让子类根据不同的需求去实现。
AQS中的方法
可重写的方法
基于AQS自定义锁,简单实现lock和unlock方法
public class MyLock implements Lock {
private final Sync sync;
public MyLock() {
this.sync = new Sync();
}
static class Sync extends AbstractQueuedSynchronizer {
@Override
protected boolean tryAcquire(int acquires) {
//获取当前线程
final Thread current = Thread.currentThread();
//获取当前同步状态
int c = getState();
if (c == 0) {
//cas方式设置同步状态
if (compareAndSetState(0, acquires)) {
//设置当前线程独占访问权限
setExclusiveOwnerThread(current);
return true;
}
}
//判断当前线程是否有访问权限,对可重入锁的支持
else if (current == getExclusiveOwnerThread()) {
//累加后更新state值
int nextc = c + acquires;
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
@Override
protected boolean tryRelease(int releases) {
//释放锁就是更新释放后的state值,如果当前线程已经没有持有锁,就把去除独占状态
int c = getState() - releases;
if (Thread.currentThread() != getExclusiveOwnerThread())
throw new IllegalMonitorStateException();
boolean free = false;
if (c == 0) {
free = true;
setExclusiveOwnerThread(null);
}
setState(c);
return free;
}
}
@Override
public void lock() {
/**
* 调用AQS中定义的模板方法
* public final void acquire(int arg) {
* if (!tryAcquire(arg) &&
* acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
* selfInterrupt();
* }
*/
//可以理解为请求获取一把锁
sync.acquire(1);
}
@Override
public void lockInterruptibly() throws InterruptedException {
}
@Override
public boolean tryLock() {
return false;
}
@Override
public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
return false;
}
@Override
public void unlock() {
/**
* 释放锁
* 也是调用AQS中的模板方法
* public final boolean release(int arg) {
* if (tryRelease(arg)) {
* Node h = head;
* if (h != null && h.waitStatus != 0)
* unparkSuccessor(h);
* return true;
* }
* return false;
* }
*
*/
sync.release(1);
}
@Override
public Condition newCondition() {
return null;
}
}
测试类
public class MyLockDemo {
static MyLock myLock = new MyLock();
public static void main(String[] args) {
new Thread(() -> {
try {
myLock.lock();
for (int i = 0; i < 4; i++) {
System.out.println(Thread.currentThread().getName() + ": " + i);
//休眠1秒,故意等待CPU重新分配时间片
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
myLock.unlock();
}
}).start();
new Thread(() -> {
try {
myLock.lock();
for (int i = 0; i < 4; i++) {
System.out.println(Thread.currentThread().getName() + ": " + i);
//休眠1秒,故意等待CPU重新分配时间片
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
myLock.unlock();
}
}).start();
}
}
必须等一个线程执行完之后另一个线程才能够执行,证明了自定义锁达到了期望的效果。