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

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


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


  java.lang.IllegalMonitorStateException:您不拥有该锁


这是根据API


  release()如果调用线程是互斥体,则执行一次释放
  获取它的相同线程。


所以基本上这是不可能的,因为回调将永远是另一个线程。还有其他方法可以做到这一点吗?

谢谢你的建议

-塔莎

最佳答案

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

08-04 16:06