1、队列同步器概念
- 队列同步器是用来构建锁的基础,它使用一个int变量表示资源的被锁状态,使用FIFO队列来控制线程对资源的加锁。即线程必须先进入队列等待,当资源空闲允许后才能对资源加锁。
- 它提供线程安全地访问状态:
- getState():获取状态
- setState(int newState):设置状态
- compareAndSetState(int expect,int update):使用CAS操作设置当前状态值
- 支持共享、独占锁方式。
- 共享锁:同一资源可被多个线程同时加锁。
- 独占锁即是同一时刻只有一个线程可以对资源加锁,而其他线程只能等待;仅当该线程释放锁时,其他线程才可对资源加锁。
- 仅提供5个可重写的方法
- protected boolean tryAcquire(int arg):独占式获取同步状态,使用CAS操作设置同步状态
- protected boolean tryRelease(int arg):独占式释放同步状态
- protected int tryAcquireShared(int arg):共享式获取同步状态,返回值>=0表示成功
- protected boolean tryReleaseShared(int arg):共享式释放同步状态
- protected boolean isHeldExclusively():当前同步器是否在独占模式下被线程占用
2、自定义同步器
- 实现一个同步器Sync,并继承AbstractQueuedSynchronizer抽象类。其重写3个方法,isHeldExclusively()、tryAcquire(int acquires)、tryRelease(int release)
- 然后Mutex类实现Lock接口,以便我们对资源的加锁、解锁。注意到,实现Lock接口的函数中,我们是使用同步器的方法对资源加锁、解锁的。
public class Mutex implements Lock{
private final Sync sync=new Sync();
//对资源加锁
@Override
public void lock() {
// TODO Auto-generated method stub
sync.acquire(1);
}
//中断方式加锁
@Override
public void lockInterruptibly() throws InterruptedException {
// TODO Auto-generated method stub
sync.acquireInterruptibly(1);
}
//新建一个Condition队列
@Override
public Condition newCondition() {
// TODO Auto-generated method stub
return sync.newCondition();
}
//尝试获取锁
@Override
public boolean tryLock() {
// TODO Auto-generated method stub
return sync.tryAcquire(1); //尝试对资源加锁
}
//以超时模式获取锁
@Override
public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException {
// TODO Auto-generated method stub
return sync.tryAcquireNanos(1, unit.toNanos(timeout));
}
//解锁
@Override
public void unlock() {
// TODO Auto-generated method stub
sync.release(1); //对资源解锁
}
//是否被锁
public boolean isLock(){
return sync.isHeldExclusively(); //是否被独占
}
//是否有线程等待
public boolean hasQueuedThreads(){
return sync.hasQueuedThreads(); //队列中是否有线程
}
//自定义同步器
private static class Sync extends AbstractQueuedSynchronizer{
//是否被线程独占
@Override
protected boolean isHeldExclusively(){
return getState()==1; //state为1时表示出于占用状态
}
//当状态为0时获得锁
@Override
public boolean tryAcquire(int acquires){
if(compareAndSetState(0,1)){
setExclusiveOwnerThread(Thread.currentThread()); //设置当前线程独占
return true;
}
return false;
}
//释放锁,将状态设置为0
@Override
public boolean tryRelease(int release){
if(getState()==0)
throw new IllegalMonitorStateException();
setExclusiveOwnerThread(null);
setState(0);
return true;
}
//新建一个Condition队列,这个队列用于存放需等待资源的线程
Condition newCondition(){
return new ConditionObject();
}
}
}
3、AbstractQueuedSynchronizer源码分析
以后补上