我正在尝试测试可撤销的Apache Curator中的Locking。我有两个试图获取锁的线程。如果第一个测试获得了锁,则第二个线程可以要求第一个线程释放锁,以便第二个线程可以获取它
RetryPolicy retryPolicy = new ExponentialBackoffRetry(baseSleepTimeMills, maxRetries);
CuratorFramework client = CuratorFrameworkFactory.newClient(hosts, retryPolicy);
client.start();
final InterProcessMutex lock = new InterProcessMutex(client, lockBasePath);
Collection<String> nodes = lock.getParticipantNodes();
lock.makeRevocable(new RevocationListener<InterProcessMutex>(){
@Override
public void revocationRequested(InterProcessMutex lock1) {
try {
if(lock.isAcquiredInThisProcess()){
lock.release();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
if(nodes!=null && !nodes.isEmpty()){
Revoker.attemptRevoke(client, nodes.iterator().next());
}
if (lock.acquire(waitTimeSeconds, TimeUnit.SECONDS)) {
try {
doSomeWork(lockName);
} finally {
lock.release();
}
} else {
System.err.printf("%s timed out after %d seconds waiting to acquire lock on %s\n",
lockName, waitTimeSeconds, lockPath);
}
问题是,当第二个线程调用tryRevoke时,在第一个进程上调用了回调异步方法,但是由于它的回调方法是第三个线程,并且如果该调用方法调用了lock.release则抛出异常
java.lang.IllegalMonitorStateException:您不拥有该锁
这是根据API
release()如果调用线程是互斥体,则执行一次释放
获取它的相同线程。
所以基本上这是不可能的,因为回调将永远是另一个线程。还有其他方法可以做到这一点吗?
谢谢你的建议
-塔莎
最佳答案
您的RevocationListener应该中断持有锁的线程。然后,该线程可以释放锁。