利用AQS实现一个简单的不可重入锁
package org.example.Pool;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
@Slf4j(topic = "c.TestAqs")
public class TestAqs {
public static void main(String[] args) {
MyLock lock = new MyLock();
new Thread(() -> {
lock.lock();
try {
log.debug("已经获得锁啦");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}, "t1").start();
new Thread(() -> {
lock.lock();
try {
log.debug("已经获得锁啦");
} finally {
lock.unlock();
}
}, "t2").start();
}
}
//自定义锁(不可重入)
class MyLock implements Lock {
//独占锁 //同步器类
class MySync extends AbstractQueuedSynchronizer {
@Override
protected boolean tryAcquire(int arg) {
//将state 从 0 改成 1 获得锁
if (compareAndSetState(0, 1)) {
//加上锁,并且设置owner设置为当前线程
setExclusiveOwnerThread(Thread.currentThread());
return true;
}
return false;
}
@Override
protected boolean tryRelease(int arg) {
//这里需要注意执行顺序,把setExclusiveOwnerThread(null);放在前面是因为state是volatile的,
// 可以保证执行顺序(有写屏障),保证设置锁主人可见,并且防止指令重排
setExclusiveOwnerThread(null);
setState(0);
return true;
}
//是否持有锁?
@Override
protected boolean isHeldExclusively() {
return getState() == 1;
}
public Condition newCondition() {
return new ConditionObject();
}
}
private MySync sync = new MySync();
//加锁 如果加锁不成功,就进入队列等待
@Override
public void lock() {
sync.acquire(1); //这里的1指的是把state改成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 sync.tryAcquireNanos(1, unit.toNanos(time));
}
//解锁
@Override
public void unlock() {
// sync.tryRelease(1); //这个方法只会释放锁,并不会唤醒正在等待的线程
sync.release(1);
}
//条件变量
@Override
public Condition newCondition() {
return sync.newCondition();
}
}