package com.zh.thread.aqs;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
/**
*
* @author zengHao
*
*/
public class AqsLock implements Lock{
private Helper helper = new Helper();
/**
* 将子类定义为非公共内部帮助器类,
* 可用它们来实现其封闭类的同步属性
* @author zengHao
*
*/
private class Helper extends AbstractQueuedSynchronizer{
@Override
protected boolean tryAcquire(int arg) {
//获取同步状态
int state = getState();
Thread t = Thread.currentThread();
//第一个线程进入,可拿到锁,返回true
//第二个线程进入,则无法拿到锁,返回false。但如果当前进来的线程与保存的线程是同一线程,则可拿到锁,更新状态值
if(state == 0) {
if(compareAndSetState(0, arg)) {
setExclusiveOwnerThread(Thread.currentThread());
return true;
}
//当前进来的线程与保存的线程是同一线程(锁重入处理)
}else if(getExclusiveOwnerThread() == t){
setState(state + 1);
return true;
}
return false;
}
@Override
protected boolean tryRelease(int arg) {
//锁的获取与释放一一对应,如果不对应则抛出异常
if(Thread.currentThread() != getExclusiveOwnerThread()) {
throw new RuntimeException();
}
//获取状态-1,
int state = getState()-arg;
boolean flag = false;
//当state等于0时,表示所有重入锁均已释放
if(state == 0) {
//清空
setExclusiveOwnerThread(null);
flag = true;
}
//当state不等于0时,还是设置为之前的状态
setState(state);
return flag;
}
Condition newCondition() {
return new ConditionObject();
}
}
@Override
public void lock() {
helper.acquire(1);
}
@Override
public void lockInterruptibly() throws InterruptedException {
helper.acquireInterruptibly(1);
}
@Override
public boolean tryLock() {
return helper.tryAcquire(1);
}
@Override
public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
return helper.tryAcquireNanos(1, unit.toNanos(time));
}
@Override
public void unlock() {
helper.release(1);
}
@Override
public Condition newCondition() {
return helper.newCondition();
}
}
测试:
package com.zh.thread.lock;
import com.zh.thread.aqs.AqsLock;
public class Sequence2 {
private int value;
private AqsLock lock = new AqsLock();
public void a() {
lock.lock();
System.err.println("a");
b();
lock.unlock();
}
public void b() {
lock.lock();
System.err.println("b");
lock.unlock();
}
public static void main(String[] args) {
Sequence2 sequence = new Sequence2();
new Thread(new Runnable() {
@Override
public void run() {
sequence.a();
}
}).start();
}
}
结果