什么是AQS
AQS,指的是AbstractQueuedSynchronizer,它提供了一种实现阻塞锁和一系列依赖FIFO等待队列的同步器的框架,ReentrantLock、Semaphore、CountDownLatch、CyclicBarrier等并发类均是基于AQS来实现的。
AQS使用方式和其中的设计模式
继承,模板方法设计模式
独占式锁代表:ReentrantLock
共享式锁代表:ReadLock
模板方法:
独占式获取
accquire
acquireInterruptibly
tryAcquireNanos
共享式获取
acquireShared
acquireSharedInterruptibly
tryAcquireSharedNanos
独占式释放锁
release
共享式释放锁
releaseShared
需要子类覆盖的流程方法
独占式获取 tryAcquire
独占式释放 tryRelease
共享式获取 tryAcquireShared
共享式释放 tryReleaseShared
这个同步器是否处于独占模式 isHeldExclusively
同步状态state:
getState:获取当前的同步状态
setState:设置当前同步状态
compareAndSetState 使用CAS设置状态,保证状态设置的原子性
LockSupport
主要用于将一个线程设置为阻塞状态,或者唤醒线程
pack 阻塞
unpack 唤醒
独占式流程
自实现ReentrantLock
public class MyReentrantLock implements Lock {
//state 表示获取到锁 state=1 获取到了锁,state=0,表示这个锁当前没有线程拿到
private static class Sync extends AbstractQueuedSynchronizer {
//是否处于独占模式
@Override
protected boolean isHeldExclusively() {
return getState() == 1;
}
//尝试获取锁
@Override
protected boolean tryAcquire(int arg) {
if (compareAndSetState(0, 1)) {
//设置当前线程为锁拥有者
setExclusiveOwnerThread(Thread.currentThread());
return true;
}
return false;
}
//尝试释放该锁
@Override
protected boolean tryRelease(int arg) {
if(getState() == 0){//当前状态为未持有锁状态,则直接抛错
throw new UnsupportedOperationException();
}
//设置锁的持有者为null
setExclusiveOwnerThread(null);
setState(0);
return true;
}
private Condition newCondition(){
return new ConditionObject();
}
}
static Sync sync = new Sync();
@Override
public void lock() {
sync.acquire(1);
}
@Override
public void lockInterruptibly() throws InterruptedException {
sync.acquireInterruptibly(1);
}
@Override
public boolean tryLock() {
return sync.tryAcquire(1);
}
@Override
public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
return sync.tryAcquireNanos(1,unit.toNanos(time));
}
@Override
public void unlock() {
sync.release(1);
}
@Override
public Condition newCondition() {
return sync.newCondition();
}
}
public class AQSTest {
static Lock lock = new MyReentrantLock();
static class MyThread extends Thread {
@Override
public void run() {
lock.lock();
try {
System.out.println(Thread.currentThread().getName() + " start to do work");
Thread.sleep(5);
System.out.println(Thread.currentThread().getName() + " work done");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
new MyThread().start();
}
}
}
运行结果:
Thread-0 start to do work
Thread-0 work done
Thread-4 start to do work
Thread-4 work done
Thread-2 start to do work
Thread-2 work done
Thread-1 start to do work
Thread-1 work done
Thread-3 start to do work
Thread-3 work done
根据结果显示,独占锁生效。
自实现Semaphore
原理:设置共享锁,设定同时最多可以有几个线程获取该锁
public class MySemaphore implements Lock {
Sync sync = new Sync(3);
static class Sync extends AbstractQueuedSynchronizer {
//设置AbstractQueuedSynchronizer的state的个数,根据对state的数量的判断,来实现同时最多几个线程获取锁
Sync(int count) {
if (count < 0) {
throw new IllegalArgumentException("count must 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;
}
}
}
Condition newCondition() {
return new ConditionObject();
}
}
@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 sync.newCondition();
}
}
public class MySemaphoreTest {
static MySemaphore semaphore = new MySemaphore();
static class MyThread extends Thread {
@Override
public void run() {
semaphore.lock();
try {
System.out.println(Thread.currentThread().getName() + ":" + System.currentTimeMillis());
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
semaphore.unlock();
}
}
}
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
new MyThread().start();
}
}
}
运行结果:
Thread-0:1590145302725
Thread-2:1590145302725
Thread-1:1590145302725
Thread-4:1590145304725
Thread-5:1590145304725
Thread-6:1590145304726
Thread-3:1590145306725
Thread-8:1590145306725
Thread-9:1590145306726
Thread-7:1590145308725