一、概述
- 1.是一个抽象父类,全称是AbstractQueuedSynchronizer,是阻塞式锁和相关的同步器工具的框架
- 2.用法是同步器类继承该父类,去实现父类的方法,调用同步器类的方法达到加锁、解锁等目的
二、特点
- 1.用state属性来表示资源的状态(分为独占模式和共享模式),子类需要定义如何维护这个状态,控制如何获取锁和释放锁
- 2.getState用来获取state状态
- 3.setState用来设置state状态
- 4.compareAndSetState利用cas乐观锁机制设置state状态
- 5.独占模式是只有一个线程能够访问资源,而共享模式可以允许多个线程访问资源
- 6.提供了基于FIFO(先进先出)的等待队列,类似于Monitor的EntryList
- 7.用条件变量来实现等待、唤醒机制,支持多个条件变量,类似于Monitor的WaitSet
- 8.子类主要实现的方法有tryAcquire、tryRelease、tryAcquireShared、tryReleaseShared、isHeldExclusively,默认会抛出UnsupportedOperationException
- 9.获取锁
// 如果获取锁失败
if(!tryAcquire(arg){
// 入队列,可以选择阻塞当前线程,用的是park和unpark机制
}
// 如果释放锁成功
if(tryRelease(arg)){
// 让阻塞线程恢复运行
}
三、实现不可重入锁
package com.learning.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
public class NotReentrantLock implements Lock {
/**
* 同步器类
* 独占锁实现
*/
class Sync extends AbstractQueuedSynchronizer{
/**
* 尝试获取锁
* @param arg 用于可重入锁的计数操作
* @return
*/
@Override
protected boolean tryAcquire(int arg) {
// 避免其它线程也调用该方法,只能有一个线程加锁成功
if(compareAndSetState(0, 1)){
// 加上锁,并设置owner为当前线程
setExclusiveOwnerThread(Thread.currentThread());
return true;
}
return false;
}
/**
* 尝试释放锁
* @param arg
* @return
*/
@Override
protected boolean tryRelease(int arg) {
// 将owner线程置为空,state状态设置为0,即为解锁
setExclusiveOwnerThread(null);
// volatile int state; state是volatile修饰的,改值后会加入写屏障,写屏障之前的改动都会同步到主内存中,因此setExclusiveOwnerThread要放在上面
setState(0);
return true;
}
/**
* 是否持有独占锁
* @return
*/
@Override
protected boolean isHeldExclusively() {
return getState() == 1;
}
public Condition newCondition(){
return new ConditionObject();
}
}
private Sync sync = new Sync();
/**
* 加锁(不成功则进入等待队列中等待)
*/
@Override
public void lock() {
// 当前线程尝试加锁,如果尝试加锁不成功,将当前线程放入等待队列,tryAcquire只会尝试一次
sync.acquire(1);
}
/**
* 可打断加锁
* @throws InterruptedException
*/
@Override
public void lockInterruptibly() throws InterruptedException {
sync.acquireInterruptibly(1);
}
/**
* 尝试加锁,尝试1次
* @return
*/
@Override
public boolean tryLock() {
return sync.tryAcquire(1);
}
/**
* 尝试加锁,带超时时间
* @param time
* @param unit
* @return
* @throws InterruptedException
*/
@Override
public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
return sync.tryAcquireNanos(1, unit.toNanos(time));
}
/**
* 解锁
*/
@Override
public void unlock() {
// tryRelease会将状态置为0,将owner线程置为null,不会唤醒等待队列中的阻塞线程
// release会调用tryRelease方法,改状态为0,将owner线程置为null,唤醒等待队列中的头个线程
sync.release(1);
}
/**
* 创建条件变量
* @return
*/
@Override
public Condition newCondition() {
return sync.newCondition();
}
public static void main(String[] args) {
NotReentrantLock lock = new NotReentrantLock();
new Thread(()->{
lock.lock();
try{
log.debug("locking...");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
log.debug("unlocking...");
lock.unlock();
}
}, "t1").start();
new Thread(()->{
lock.lock();
try{
log.debug("locking...");
}finally {
log.debug("unlocking...");
lock.unlock();
}
}, "t2").start();
}
}