Apache策展人锁食谱撤销

时间:2015-10-27 17:24:08

标签: java multithreading apache apache-zookeeper apache-curator

我正在尝试在Apache Curator中测试可撤销的锁定。我有两个线程试图获得一个锁。如果第一个测试获得锁定,则第二个线程可以要求第一个线程释放锁定,以便第二个线程可以获取它

        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);
        }

问题是,当第二个线程调用attemptRevoke时,在第一个进程上调用回调异步方法,但由于它的回调方法是第三个线程,并且如果调用lock.release它会抛出异常

  

java.lang.IllegalMonitorStateException:您没有锁

这是根据api

  

release()如果调用线程是,则执行互斥锁的一个版本   获得它的同一个线程。

所以基本上这是不可能的,因为回调总是另一个线程。有没有其他方法来实现这一目标?

感谢您的任何建议

-Tatha

2 个答案:

答案 0 :(得分:0)

您的RevocationListener应该中断持有锁的线程。然后,该线程可以释放锁。

答案 1 :(得分:0)

您可以使用InterProcessSemaphoreMutex代替InterProcessMutex来释放另一个帖子中的锁定。

参考:Ability to release an InterProcessMutex from another thread #117