Как заблокировать метод Java для защиты нескольких вызовов

У меня есть приложение что каждые 15 минут или также - репликация от удаленной базы данных. Это просто сохраняет эти два репозитория в синхронизации. После того как эта репликация идет, не возможно сделать это снова. Я имею, устанавливают следующую структуру, но я не уверен, является ли это корректный подход.

public class ReplicatorRunner {

       private static Lock lock = new ReentrantLock();

       public replicate() {

           if (lock.tryLock()) {
               try {
                   // long running process
               } catch (Exception e) {                   
               } finally {
                   lock.unlock();
               }               
           } else {
               throw new IllegalStateException("already replicating");
           }

       }

}

public class ReplicatorRunnerInvocator {

    public void someMethod() {

        try {
            ReplicatorRunner replicator = new ReplicatorRunner();
            replicator.replicate();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        }

    }

}

ReplicatorRunner класс, владеющий методом replicate который может только быть выполнен по одному.

Править. Мне нужен следующий вызов для сбоя (не блок), если метод уже работает на каком-либо экземпляре.

9
задан Dave Jarvis 11 March 2010 в 22:29
поделиться

5 ответов

Выглядит хорошо. ReentrantLock.tryLock () предоставит блокировку только одному потоку, поэтому synchronized не требуется. Это также предотвращает блокировку, присущую синхронизации, которая, по вашему мнению, является обязательной. ReentrantLock поддерживает сериализацию, поэтому должен работать во всем кластере.

Дерзайте.

4
ответ дан 4 December 2019 в 23:39
поделиться

взгляните на класс Semaphore здесь или отметьте метод как синхронизированный {{1} } поток, выполняющий метод в любой момент времени, владеет блокировкой на нем, избегая того, чтобы другие потоки вызывали метод, пока его выполнение не закончится.
Изменить: если вы хотите, чтобы другие потоки завершились с ошибкой , вы можете использовать Блокировку и проверить, доступна ли блокировка с помощью метода tryLock.

0
ответ дан 4 December 2019 в 23:39
поделиться

Измените public replicate () на public synchronized replicate ()

Таким образом, при репликации будет разрешен доступ только к по одному потоку за раз. Вы также сможете удалить ReentrantLock и весь связанный с ним код.

1
ответ дан 4 December 2019 в 23:39
поделиться

В итоге я использовал следующее:

public class ReplicatorRunner {

       private static Semaphore lock = new Semaphore(1);

       public replicate() {

           if (lock.tryAcquire()) {
               try {                              
                   // basic setup                  
                   Thread t = new Thread(new Runnable() {
                       public void run() {
                           try {
                               // long running process                               
                           } catch Exception (e) {
                               // handle the exceptions
                           } finally {
                               lock.release();
                           }
                       }
                   })
                   t.start();

               } catch (Exception e) {
                   // in case something goes wrong
                   // before the thread starts
                   lock.release();
               }              
           } else {
               throw new IllegalStateException("already replicating");
           }

       }

}

public class ReplicatorRunnerInvocator {

    public void someMethod() {

        try {
            ReplicatorRunner replicator = new ReplicatorRunner();
            replicator.replicate();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        }

    }

}
1
ответ дан 4 December 2019 в 23:39
поделиться

Не вдаваясь в подробности ReentrantLock, мне приходит в голову, что это предотвращение нескольких подпрограмм одновременной репликации будет ограничено одним экземпляром JVM.

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

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

0
ответ дан 4 December 2019 в 23:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: