AQS原理
AQS的等待队列是JAVA实现的,Synchronized的monitor是C++实现的.
AQS子类方法
AQS的使用
自定义一个锁,并设置它的阻塞队列
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
@Slf4j(topic = "TC53")
public class TC53 {
public static void main(String[] args) {
MyLock lock =new MyLock();
new Thread(()->{
lock.lock();
try {
log.debug("locking....");
}finally {
log.debug("unlocking....");
lock.unlock();
}
},"锁测试1").start();
new Thread(()->{
lock.lock();
try {
log.debug("locking....");
}finally {
log.debug("unlocked....");
lock.unlock();
}
},"锁测试2").start();
new Thread(()->{
lock.lock();
log.debug("locking....");
//不可重入锁,同一个线程再次上锁时,不会成功,除非先开锁
lock.lock();
log.debug("重入锁....");
try {
log.debug("locking....");
}finally {
log.debug("unlocked....");
lock.unlock();
}
},"重入锁测试").start();
}
}
//自定义锁,不可重入锁
class MyLock implements Lock {
//独占锁 同步器类
class Mysync extends AbstractQueuedSynchronizer{
//state==0; 无锁状态; state==1;有锁状态
@Override //获取锁
protected boolean tryAcquire(int arg) {
if (compareAndSetState(0,1)) {
setExclusiveOwnerThread(Thread.currentThread());
return true;
}
return false;
}
@Override //释放锁
protected boolean tryRelease(int arg) {
setExclusiveOwnerThread(null);
setState(0); //volatile 写屏障保证该屏障前的共享变量操作都会被同步到主存中
return true;
}
@Override //是否持有独占锁
protected boolean isHeldExclusively() {
return getState()==1;
}
public Condition newCondition() {
return new ConditionObject();
}
}
private Mysync sync = new Mysync();
@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 //在time时间内不停的尝试加锁
public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
return sync.tryAcquireNanos(1,unit.toNanos(time));
}
@Override //解锁
public void unlock() {
sync.release(1); //解锁并唤醒阻塞队列里的任务
// sync.tryRelease(1); //只解锁,不唤醒阻塞队列里的任务
}
@Override //创建条件变量
public Condition newCondition() {
return sync.newCondition();
}
}