AQS的release方法为什么不能唤醒被acquire阻塞的应用
来源:4-11 Redis集群
qq_君君晨晨_0
2020-10-03
这里我实现了AQS中的tryAcquire和tryRelease方法,我想的是调用tryAcquire返回fasle会阻塞线程,这个确实做到了,但是我调用tryRelease返回true却不能释放锁。
具体流程:我创建了一个AQS,然后把它传入到线程中,在参数为1的线程中获得共享资源(tryAcquire返回true),在参数为2的线程中阻塞(tryAcquire返回false),然后我想的是当参数为1的线程释放掉锁之后,参数为2的线程应该可以被唤醒然后继续执行,然而事实是参数2的线程在参数1线程释放掉锁后依旧阻塞。
class runnable implements Runnable{
int arg;
MyAbstractQuenedSynchronizer aqs;
@Override
public void run() {
try {
if(arg!=1){
System.out.println("被阻塞"+Thread.currentThread());
}
aqs.acquire(arg);
System.out.println("开始执行"+Thread.currentThread());
Thread.sleep(3000);
System.out.println("执行结束"+Thread.currentThread());
aqs.release(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public runnable(int arg,MyAbstractQuenedSynchronizer aqs){
this.aqs = aqs;
this.arg = arg;
}
}
public class MyAbstractQuenedSynchronizer extends AbstractQueuedSynchronizer{
@Override
protected boolean tryAcquire(int arg) {
//参数是1可以,其它不可以
if(arg==1){
setExclusiveOwnerThread(Thread.currentThread());
return true;
}else{
return false;
}
}
@Override
protected boolean tryRelease(int arg) {
System.out.println("释放锁"+Thread.currentThread());
setExclusiveOwnerThread(null);
return true;
}
public static void main(String[] args) {
MyAbstractQuenedSynchronizer aqs = new MyAbstractQuenedSynchronizer();
new Thread(new runnable(1,aqs)).start();
new Thread(new runnable(2,aqs)).start();
new Thread(new runnable(2,aqs)).start();
}
}
实际输出:
开始执行Thread[Thread-0,5,main]
被阻塞Thread[Thread-2,5,main]
被阻塞Thread[Thread-1,5,main]
执行结束Thread[Thread-0,5,main]
释放锁Thread[Thread-0,5,main]
可以看出来,释放掉锁后其它线程依旧阻塞。
写回答
1回答
-
qq_君君晨晨_0
提问者
2020-10-04
这个我看了以下源码已经会了,因为release唤醒被阻塞的线程后,被唤醒的线程还会调用tryAcquire方法,按我写的这个它不会获取成功,会再次进入阻塞。
10
相似问题