2

我正在尝试测试 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() 如果调用线程与获取它的线程相同,则执行一次互斥锁释放。

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

感谢您的任何建议

-塔塔

4

2 回答 2

1

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

于 2015-10-28T19:44:25.110 回答
1

您可以使用InterProcessSemaphoreMutex而不是InterProcessMutex释放另一个线程中的锁。

ref:能够从另一个线程释放 InterProcessMutex #117

于 2017-05-17T09:27:36.080 回答