Reputation: 1293
I am trying to test the revocable Locking in Apache Curator. I have two threads which tries to acquire a lock. If the first test acquires the lock, the second thread can ask the first thread to release the lock so that the 2nd thread can acquire it
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);
}
The problem is, when the 2nd thread calls the attemptRevoke, the callback async method is called on the first process, but since its a call back method that's a third thread, and if that invokes the lock.release it throws an Exception
java.lang.IllegalMonitorStateException: You do not own the lock
That is as per the api
release() Perform one release of the mutex if the calling thread is the same thread that acquired it.
So basically this is never possible because callbacks will always be another thread. Is there any other way to achieve this?
Thanks for any suggestions
-Tatha
Upvotes: 2
Views: 2085
Reputation: 969
You can use InterProcessSemaphoreMutex
instead of InterProcessMutex
to release the lock in another thread.
ref: Ability to release an InterProcessMutex from another thread #117
Upvotes: 3
Reputation: 2956
Your RevocationListener should interrupt the thread that holds the lock. Then, that thread can release the lock.
Upvotes: 1