1

简而言之:我想与一个客户端创建一个锁并与另一个客户端释放它;所以我试图为此使用撤销。它不工作。更多细节(和我的代码)如下。任何帮助表示赞赏!

long:有一个系统,其中一个线程(带有自己的客户端)设置第一个锁(更新),然后第二个线程(带有可能与原始客户端相同或不同的客户端)将设置第二个锁;然后做一些工作,然后释放那个锁,然后释放第一个锁这个代码通过让两个不同的客户端获得锁来模拟两个线程。

但是,第二个客户端无法从第一个客户端撤消锁定。永远不会触发“撤销侦听器”。已经在网上搜索并没有找到示例。此代码假定您在本地主机的端口 2181 上运行了一个 zookeeper 服务器

理想情况下,我还想从其他地方快速查看锁是否到位,但也许超时时间很短(5 毫秒)的获取可以实现这一点。

另外,释放锁后收割锁是个好主意吗?(不堵塞系统?)

谢谢

-吉尔

ps: 也贴在 apache curator user mailing list

如果我有答案,我会交叉发布答案。

从邮件列表中得到了一个答案:Jordan Zimmerman 晚上 8:46(13 小时前)有很多问题:

  • 文档对此并不清楚,但必须在获取锁之前调用 makeRevocable() 。请提交 Jira/PR 以修复文档。
  • 在您的测试中,Revoker.attemptRevoke 使用了不正确的路径。一定是锁的路径,所以:“Revoker.attemptRevoke(client2, ipMutex.getLockPath());”</li>
  • 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");
            }

        }

    }
}
4

0 回答 0