Параллелизм: как предотвратить одновременное выполнение двух методов в двух разных классах? - PullRequest
0 голосов
/ 10 декабря 2018

У меня есть сценарий использования, в котором я должен предотвратить одновременную работу двух разных методов в двух разных классах, т. Е. Если у класса A есть метод X, а у класса B есть метод Y, я должен убедиться, что при использовании метода Xвыполнено, я не должен позволять методу Y выполнять или блокировать выполнение, пока не будет завершен methodX.

class A{
    @Scheduled
    methodX(){
    }
}

class B{
    methodY(){}
}

Немного фона, Здесь methodX - это запланированный процесс, который отвечает за чтение данных с удаленного компьютера.базы данных, преобразования, сделать некоторые сопоставления и сохранить его в локальной базе данных.

methodY - это общая реализация (может быть вызвана вызовом REST или другим запланированным процессом), которая считывает данные из разных источников, один изисточником являются данные, которые хранятся methodX, после прочтения он также выполняет некоторые сопоставления и отправляет данные в другую систему.

Поскольку мне приходится синхронизировать два разных метода внутри двух разных классов, ключевое слово synchronized илиблок - не правильное решение.

Я использовал семафот общего подсчетаздесь в методе X и методе Y, то есть

class A{
    @Scheduled
    methodX(){
        if(sharedSemaphore.tryAcquire()){       
            // read data, do mappings etc.
            ...
            ...

            sharedSemaphore.release();
        }
    }
}

class B{
    methodY(){
     if(sharedSemaphore.tryAcquire()){
         ...
         ...
         ...
         sharedSemaphore.release();
     }
    }
}

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

Ответы [ 2 ]

0 голосов
/ 10 декабря 2018

Если вы можете извлечь общий код из MethodX и MethodY, то вы можете просто избежать синхронизации.

Хотя, как правило, это не очень хорошее решение для веб-сервера и остальных API, поскольку, скорее всего, у вас будет горизонтальное масштабирование или балансировка нагрузки между серверами.

Итак, все сводится к сериализации кода (путем блокировки?) На разных машинах.Не уверен, какой у вас технический стек, но варианты могут использовать блокировку на основе базы данных, mysql get_lock или oracle dbms_lock, некоторое состояние базы данных (это почти вы используете свой собственный механизм блокировки) или очередь задач, если вы используете какой-либо обмен сообщениямиРамка.Также вы можете использовать актеров Акка.

0 голосов
/ 10 декабря 2018

Если это происходит из двух разных потоков, то почему вы не можете сохранить какое-то состояние в БД?например,

  1. methodX запускается планировщиком, затем он обновляет некоторое состояние в таблице.
  2. methodY запускается REST API или другим планировщиком, а затем сначала проверяет состояние и обрабатывает соответственно.
...