自定义同步组件构建实例及AbstractQueuedSynchr
2017-02-06 本文已影响65人
higher2017
以下知识参考《Java并发编程的艺术》
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
/**
* Mutex: 独占式锁实例(自定义同步组件)
* @author JM
* @date 2017-2-5 下午9:43:57
* @since JDK 1.7
*/
public class Mutex implements Lock{
//静态内部类,自定义同步器
private static class Sync extends AbstractQueuedSynchronizer{
//是否处于占有状态
protected boolean isHeldExclusively() {
return getState() == 1;
}
//当前状态为0时获取锁,然后进行CAS设置同步状态
public boolean tryAcquire(int acquires){
//compareAndSetState(int expect,int update):使用CAS设置当前状态,如果状态为expect则将状态修改为update
if(compareAndSetState(0, 1)){
//标记正在拥有这个锁的线程
setExclusiveOwnerThread(Thread.currentThread());
return true;
}
return false;
}
//释放锁,将状态设置为0。 独占式释放同步状态,等待获取同步状态的线程将有机会获取同步状态
protected boolean tryRelease(int releases){
if(getState() == 0) throw new IllegalMonitorStateException();
//没有线程拥有这个锁
setExclusiveOwnerThread(null);
setState(0);
return true;
}
//返回一个Condition,每个condition都包含一个condition队列
Condition newCondition(){
return new ConditionObject();
}
}
private final Sync sync = new Sync();
@Override
public void lock(){
// 独占式获取同步状态,如果当前线程获取同步状态成功,则由该方法返回。<br/>
// 否则将会进入同步队列等待,该方法将会调用重写的tryAcquire(int arg)方法.<br/>
sync.acquire(1);
}
@Override
public void lockInterruptibly() throws InterruptedException {
//与acquire(int arg)相同,但是该方法对中断有响应
//如果线程未被中断且当前线程获取不到同步状态时,将会进入同步队列。否则如果线程被中断,则该方法会抛出InterruptedException异常
sync.acquireInterruptibly(1);
}
/**
*
*/
@Override
public boolean tryLock() {
return sync.tryAcquire(1);
}
@Override
public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
//在acquireInterruptibly(int arg)基础上增加了超时限制,如果当前线程在超时时间内没有获取到同步状态,将会返回false。获取到就返回true
return sync.tryAcquireNanos(1, unit.toNanos(time));
}
@Override
public void unlock() {
sync.release(1);
}
@Override
public Condition newCondition() {
return sync.newCondition();
}
}
类Mutex就是一个自定义的同步组件,在Mutex中定义了Sync静态内部类,Sync继承了 AbstractQueuedSynchronizer(队列同步器)并实现了独占式获取(tryAcquire(int arg))和释放(tryRelease(int release))同步状态的方法。用户使用Mutex并不会直接和静态内部类Sync的实例打交道,而是调用Mutex提供的方法。这样可以大大降低实现一个可靠自定义同步组件的门槛