如何实现
1 创建一个名字为 MyTestLock接口 implment Lock
2 在 MyTestLock中 创建一个内部类 MyTestSyn 但是继承AbstarctQueuedSynchronizer
3 AbstarctQueuedSynchronizer 中有tryAcquire,tryrelease 方法必须要实现的
几个关键api
获得锁时用:
//获得锁的线程是哪个 ,要记录下
setExclusiveOwnerThread(Thread.currentThread());
//cas 操作获得锁
compareAndSetState(0,1)
释放锁用:
setExclusiveOwnerThread(null);//当前锁已经没有所属者
setState(0);//同步状态变量为0
独占锁
/*获得锁*/
private static class Sync extends AbstractQueuedSynchronizer {
@Override
protected boolean tryAcquire(int arg) {
if(compareAndSetState(0,1)){
setExclusiveOwnerThread(Thread.currentThread());
return true;
}
return false;
}
/*释放锁*/
@Override
protected boolean tryRelease(int arg) {
if(getState()==0){
throw new IllegalMonitorStateException();
}
setExclusiveOwnerThread(null);
setState(0);
//compareAndSetState(1,0);
return true;
}
}
可重入
考虑状态+1 表示可重入,但需要判断是不是自己这个线程,是的话才叫可重入。
else if(getExclusiveOwnerThread()==Thread.currentThread()){
setState(getState()+1);
释放的时候注意 -1;
// 当状态为0的时候获取锁
private static class Sync extends AbstractQueuedSynchronizer {
@Override
public boolean tryAcquire(int acquires) {
if (compareAndSetState(0, 1)) {
setExclusiveOwnerThread(Thread.currentThread());
return true;
}else if(getExclusiveOwnerThread()==Thread.currentThread()){
setState(getState()+1);
return true;
}
return false;
}
// 释放锁,将状态设置为0
@Override
protected boolean tryRelease(int releases) {
if(getExclusiveOwnerThread()!=Thread.currentThread()){
throw new IllegalMonitorStateException();
}
if (getState() == 0) {
throw new IllegalMonitorStateException();
}
setState(getState()-1);
if(getState()==0){
setExclusiveOwnerThread(null);
}
return true;
}
}