学以致用,学习过程中自己动手实践。自定义类MyLock实现Lock接口,类中的Helper 属性继承AbstractQueuedSynchronizer重写了tryAcquire和tryRelease方法。如果想实现一把共享的锁,可以实现tryAcquireShared 和tryReleaseShared
package com.example.consumer.AbstractQueuedSynchorizer;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
public class MyLock implements Lock {
private Helper helper =new Helper();
private class Helper extends AbstractQueuedSynchronizer{
@Override
protected boolean tryAcquire(int arg) {
Thread thread=Thread.currentThread();//获取当前线程
//获取AbstractQueuedSynchronizer中记录的状态 0 代表还没有线程获取锁
int state=getState();
if (state==0){
//如果没有线程拿到锁,则对当前线程进行cas操作设置锁状态标志,如果cas操纵成功则
if (compareAndSetState(0,arg)){
//将AbstractQueuedSynchronizer记录的线程设置为当前线程,然后返回true代表
获取锁成功
setExclusiveOwnerThread(thread);
return true;
}
}
//如果当前锁的状态不为0,则判断AbstractQueuedSynchronizer中保存的线程是否是当前线
程,如果是则将所状态标志位加arg,返回true成功。否则返回false失败
else if (getExclusiveOwnerThread()==thread){
setState(state+arg);
return true;
}
return false;
}
@Override
protected boolean tryRelease(int arg) {
Thread t=Thread.currentThread();//拿到当前线程
int state=getState();//拿到锁状态标志
//判断当前线程和AbstractQueuedSynchronizer中记录的线程是否一致,不一致返回一个运行时异常
if (getExclusiveOwnerThread()!=t){
throw new RuntimeException();
}
//释放所一定是只有一个线程且为当前线程在进行操作
boolean flag=false;
//计算释放一次锁之后线程的状态,如果锁状态为0,则释放所成功并将
AbstractQueuedSynchronizer中保存的当前线程设置为null
state=state=arg;
if (state==0){
setExclusiveOwnerThread(null);
return true;
}
//设置计算之后的锁状态
setState(state);
return false;
}
protected 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.tryRelease(1);
}
@Override
public Condition newCondition() {
return helper.newCondition();
}
}