简短:我想用一个客户端创建一个锁,然后用另一个客户端释放它;所以我试图为此目的使用撤销。它不起作用。更多细节(和我的代码)如下。 任何帮助表示赞赏!
long:有一个系统,其中一个线程(具有自己的客户端)设置第一个锁(更新),然后第二个线程(客户端可能与原始客户端可能相同或不同)将设置第二个锁;然后做一些工作,然后释放该锁,然后释放第一个锁,这个代码通过让两个不同的客户端获得锁来模拟两个线程。
但是,第二个客户端无法撤消第一个客户端的锁定。永远不会触发“撤销监听器”。已经扫过网络,没有找到例子。 此代码假定您在本地主机上的端口2181上运行了zookeeper服务器
理想情况下,我还想从其他地方快速查看锁定是否到位,但也许可以通过非常短的超时(5毫秒)来完成。
另外,释放它们后收获锁是否是个好主意? (不要堵塞系统?)
感谢
-Jill
ps:也发布在apache curator用户邮件列表
上如果我有答案,我会交叉发帖。
从邮件列表中得到一个答案:Jordan Zimmerman 8:46 PM(13小时前)有一个 问题数量:
- 文档不清楚,但必须在获取锁之前调用makeRevocable()。请提交Jira / PR以修复文档。
- 在您的测试中,Revoker.attemptRevoke使用了错误的路径。它必须是锁的路径,所以:“Revoker.attemptRevoke(client2, ipMutex.getLockPath());”
- InterProcessMutex跟踪拥有锁的线程。所以,lock.release();你的复兴者将无法工作。我建议使用 相反,InterProcessSemaphoreMutex。
import java.util.Collection;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.apache.curator.framework.recipes.locks.RevocationListener;
import org.apache.curator.framework.recipes.locks.Revoker;
import org.apache.curator.retry.ExponentialBackoffRetry;
public class MultipleClientExample {
/*entry point
*/
public static void main(String[] args){
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
String zookeeperConnectionString = "127.0.0.1:2181";
CuratorFramework client = CuratorFrameworkFactory.newClient(zookeeperConnectionString, retryPolicy);
client.start();
try {
System.out.println("testing locks....");
InterProcessMutex ipMutex = new InterProcessMutex(client, "/mpx-updates/guid123/update");
boolean acquired = ipMutex.acquire(3, TimeUnit.SECONDS);
System.out.println("got the lock(update)?" + acquired);
RevocationListener<InterProcessMutex> rl = new MyRevocationListener();
ipMutex.makeRevocable(rl);
InterProcessMutex ipMutex2 = new InterProcessMutex(client, "/mpx-updates/guid123/swap");
boolean a2 = ipMutex2.acquire(3, TimeUnit.SECONDS);
System.out.println("got the lock(swap)?" + a2);
System.out.println("got the first lock in this process? " + ipMutex.isAcquiredInThisProcess());
// make a new client; see if it can get the lock!
CuratorFramework client2 = CuratorFrameworkFactory.newClient(zookeeperConnectionString, retryPolicy);
client2.start();
InterProcessMutex ipMutex1Retry = new InterProcessMutex(client2, "/mpx-updates/guid123/update");
boolean a3 = ipMutex1Retry.acquire(3, TimeUnit.SECONDS);
System.out.println("got the lock(retry/update) ?" + a3);
System.out.println("got the first lock in this process? " + ipMutex1Retry.isAcquiredInThisProcess());
Revoker.attemptRevoke(client2, "/mpx-updates/guid123/update");
a3 = ipMutex1Retry.acquire(3, TimeUnit.SECONDS);
System.out.println("AGAIN: got the lock(retry/update) ?" + a3);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public class MyRevocationListener implements RevocationListener<InterProcessMutex> {
/*
* (non-Javadoc)
*
* @see org.apache.curator.framework.recipes.locks.RevocationListener#revocationRequested(java.lang.Object)
*/
@Override
public void revocationRequested(InterProcessMutex lock) {
//this seems to never be called
Collection<String> participantNodes = null;
try {
System.out.println("revocation was requested....");
System.out.println("ick ick revocation requested....");
participantNodes = lock.getParticipantNodes();
lock.release();
System.out.println("revoked lock at path: " + participantNodes);
} catch (Exception e) {
System.out.println("problem revoking lock with path: " + participantNodes + "; it was not revoked");
}
}
}
}