Apache Curator Lock Рецепты отмены

Я пытаюсь протестировать отзывную блокировку в Apache Curator. У меня есть два потока, которые пытаются получить блокировку. Если первый тест получает блокировку, второй поток может попросить первый поток снять блокировку, чтобы 2-й поток мог ее получить

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

Проблема заключается в том, что когда 2-й поток вызывает попытку Revoke, асинхронный метод обратного вызова вызывается в первом процессе, но, поскольку его метод обратного вызова является третьим потоком, и, если он вызывает блокировку.

java.lang.IllegalMonitorStateException: у вас нет блокировки

Это согласно API

release() Выполните одно освобождение мьютекса, если вызывающий поток является тем же потоком, который его получил.

Так что в принципе это никогда не возможно, потому что обратные вызовы всегда будут другим потоком. Есть ли другой способ добиться этого?

Спасибо за любые предложения

-Tatha

2 ответа

Ты можешь использовать InterProcessSemaphoreMutex вместо InterProcessMutex снять блокировку в другом потоке.

ref: Возможность освободить InterProcessMutex из другого потока #117

Ваш RevocationListener должен прервать поток, который удерживает блокировку. Затем этот поток может снять блокировку.

Другие вопросы по тегам