介绍
- Lock接口, 该接口定义了java语言中显式锁的基本方法
-
AbstractQueuedSynchronizer抽象类, 采用模版方法设计模式, 其中的模版方法实现了锁的完整流程, 而我们只需要把需要重写的方法进行一个实现即可实现自己的锁.
- protected boolean tryAcquire(int arg) – 尝试获取许可
- protected boolean tryRelease(int arg) – 尝试释放许可
- protected boolean isHeldExclusively() – 当前锁是否被占用
-
上代码
public class MyLock implements Lock {
private static class Sync extends AbstractQueuedSynchronizer {
@Override
protected boolean tryAcquire(int arg) {
int state = getState();
// 如果state状态为0 标识无锁, 反之有锁
// 第一次加锁
if (compareAndSetState(0,1)){
setExclusiveOwnerThread(Thread.currentThread());
return true;
}
// 如果当前线程与占用锁的线程一致,表明线程重入
if (Thread.currentThread() == getExclusiveOwnerThread()){
compareAndSetState(state,state+1);
return true;
}
// 返回false, 该线程将会加入到同步队列进行等待
return false;
}
@Override
protected boolean tryRelease(int arg) {
// 这个方法只有拿到线程的锁会进入, 也就是只有一个线程会进入此方法
int state = getState();
// 进行减一操作
setState(state-1);
// 如果为0 , 表明已经完全释放, 把当前占用线程设置为空
if (getState() == 0){
setExclusiveOwnerThread(null);
}
return true;
}
/**
* 判断是否被占用
* */
@Override
protected boolean isHeldExclusively() {
return getState()> 0;
}
}
private Sync sync = new Sync();
@Override
public void lock() {
sync.acquire(1);
}
@Override
public void lockInterruptibly() throws InterruptedException {
sync.acquireInterruptibly(1);
}
@Override
public boolean tryLock() {
return sync.tryAcquire(1);
}
@Override
public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
return tryLock();
}
@Override
public void unlock() {
sync.release(1);
}
@Override
public Condition newCondition() {
return null;
}
}
- 简单的可重入锁就已经完成, 关键在于加锁的时候对自身进行判断.
突发感想
代码始终不是重点, 算法,数据结构,才是真的核心, 而我们java程序员离核心总是那么远