Используйте ConcurrentHashMap для замены HazelCast IMap на блокировку ⇐ JAVA
Используйте ConcurrentHashMap для замены HazelCast IMap на блокировку
Удаление HazelCast из приложения, которому больше не требуется распределенное кэширование.
Однако мне все равно нужно сохранить синхронизированный доступ к карте, аналогичной IMap.
Сначала я хотел заменить IMap на Map и ConcurrentHashMap.
Теперь коллекция представляет собой простую карту Java, но мне все еще нужно управлять асинхронным чтением/записью в нее.
Достаточно ли ConcurrentHashMap для решения этой проблемы, или мне нужны другие решения/механизм блокировки.
Приложение использует RabbitMQ с 3 очередями.
С HazelCast у меня был IMap с объектами домена, который я блокировал в каждом потоке MQ, обращающемся к нему.
Во время инициализации пакетного задания создаются новые объекты домена и помещаются на карту.
В конце инициализации он отправляет запрос в 3 разные очереди сообщений для каждого объекта на карте.
Только один поток MQ должен иметь возможность получать объект с карты, обновлять его и помещать обратно на карту.
Может ли ConcurrentHashMap справиться с этим, мне нужно реализовать некоторую блокировку/разблокировку между Map.get и Map.put?
В HazelCast это было сделано с помощью блокировки карты.
IMap myCollection; public voidprocessMessage1(окончательный ответ MyResponse1) { // MQ-Thread1 окончательный Long myObjectId = response.getObjectId(); myCollection.lock(myObjectId); пытаться { окончательный MyObject myObject = myCollection.get(myObjectId); updateMyObject(myObject, ответ); myCollection.put(myObjectId, myObject) если (myObject.isCompleted()) { репозиторий.save(мойОбъект); } } окончательно { myCollection.unlock(myObjectId); } } public voidprocessMessage2(окончательный ответ MyResponse2) { // MQ-Thread2 // Аналогично блокировке, как и в ProcessMessage1 } public voidprocessMessage3(окончательный ответ MyResponse3) { // MQ-Thread3 // Аналогично блокировке, как и в ProcessMessage1 } Как теперь выглядит мой код, когда блокировка HazelCast и IMap изменена на ConcurrentHashMap.
@Данные @Компонент общественный класс MyCache { частные окончательные производители Map = new HashMap(); частный окончательный ConcurrentMap клиенты = новый ConcurrentHashMap(); } @Услуга общественный класс CustomerService { частный окончательный MyCache myCache; общественный CustomerService (окончательный MyCache myCache) { this.myCache = myCache; } общественный недействительный startProcessing () { ПолучитьПродюсеры(); myCache.getProducers().keySet().forEach(id -> startProcessingProducer(id)); } public void startProcessingProducer (Long ProduceId) { log.info("Началась обработка для производителяId={}", производителяId); инициализировать (идентификатор производителя); } общественная недействительная инициализация (Long ProduceId) { log.info("Инициализировать начало {}", ProduceId); конечный клиент клиент = новый клиент(); sendRabbitMq1 (идентификатор производителя); sendRabbitMq2 (идентификатор производителя); sendRabbitMq3 (идентификатор производителя); myCache.getCustomers().put(producerId, клиент); log.info("Инициализировать конец {}", ProduceId); } } @Услуга общественный класс MessageService { частный окончательный MyCache myCache; частный окончательный StorageService StorageService; public MessageService (окончательный MyCache myCache, окончательный StorageService StorageService) { this.myCache = myCache; this.storageService = StorageService; } @Бин @Транзакционный общественный Consumer response1() { верните это::processResponse1; } @Бин @Транзакционный общественный Consumer response2() { верните это::processResponse2; } @Бин @Транзакционный общественный Consumer response3() { верните это::processResponse3; } частный недействительный процессResponse1 (окончательный ответ MyResponse1) { myCache.getCustomers().computeIfPresent(response.getProducerId(), (producerId, клиент) -> updateFromResponse1 (ответ, клиент)); } частный клиент updateFromResponse1 (окончательный ответ MyResponse1, конечный клиент клиента) { log.debug("Получен ответ 1 {}", ответ); // Обновление клиента с ответом процесс (клиент, StorageService:: saveCustomer); возврат клиента; } public voidprocess(конечный клиент-клиент, конечный Consumer customerUpdateCallback) { // Обработка клиента customerUpdateCallback.accept(клиент); } } @Услуга общественный класс StorageService { частный конечный CustomerRepository customerRepository; public StorageService (окончательный CustomerRepository customerRepository) { this.customerRepository = customerRepository; } public void saveCustomer(конечный клиент) { customerRepository.save(клиент); } }
Удаление HazelCast из приложения, которому больше не требуется распределенное кэширование.
Однако мне все равно нужно сохранить синхронизированный доступ к карте, аналогичной IMap.
Сначала я хотел заменить IMap на Map и ConcurrentHashMap.
Теперь коллекция представляет собой простую карту Java, но мне все еще нужно управлять асинхронным чтением/записью в нее.
Достаточно ли ConcurrentHashMap для решения этой проблемы, или мне нужны другие решения/механизм блокировки.
Приложение использует RabbitMQ с 3 очередями.
С HazelCast у меня был IMap с объектами домена, который я блокировал в каждом потоке MQ, обращающемся к нему.
Во время инициализации пакетного задания создаются новые объекты домена и помещаются на карту.
В конце инициализации он отправляет запрос в 3 разные очереди сообщений для каждого объекта на карте.
Только один поток MQ должен иметь возможность получать объект с карты, обновлять его и помещать обратно на карту.
Может ли ConcurrentHashMap справиться с этим, мне нужно реализовать некоторую блокировку/разблокировку между Map.get и Map.put?
В HazelCast это было сделано с помощью блокировки карты.
IMap myCollection; public voidprocessMessage1(окончательный ответ MyResponse1) { // MQ-Thread1 окончательный Long myObjectId = response.getObjectId(); myCollection.lock(myObjectId); пытаться { окончательный MyObject myObject = myCollection.get(myObjectId); updateMyObject(myObject, ответ); myCollection.put(myObjectId, myObject) если (myObject.isCompleted()) { репозиторий.save(мойОбъект); } } окончательно { myCollection.unlock(myObjectId); } } public voidprocessMessage2(окончательный ответ MyResponse2) { // MQ-Thread2 // Аналогично блокировке, как и в ProcessMessage1 } public voidprocessMessage3(окончательный ответ MyResponse3) { // MQ-Thread3 // Аналогично блокировке, как и в ProcessMessage1 } Как теперь выглядит мой код, когда блокировка HazelCast и IMap изменена на ConcurrentHashMap.
@Данные @Компонент общественный класс MyCache { частные окончательные производители Map = new HashMap(); частный окончательный ConcurrentMap клиенты = новый ConcurrentHashMap(); } @Услуга общественный класс CustomerService { частный окончательный MyCache myCache; общественный CustomerService (окончательный MyCache myCache) { this.myCache = myCache; } общественный недействительный startProcessing () { ПолучитьПродюсеры(); myCache.getProducers().keySet().forEach(id -> startProcessingProducer(id)); } public void startProcessingProducer (Long ProduceId) { log.info("Началась обработка для производителяId={}", производителяId); инициализировать (идентификатор производителя); } общественная недействительная инициализация (Long ProduceId) { log.info("Инициализировать начало {}", ProduceId); конечный клиент клиент = новый клиент(); sendRabbitMq1 (идентификатор производителя); sendRabbitMq2 (идентификатор производителя); sendRabbitMq3 (идентификатор производителя); myCache.getCustomers().put(producerId, клиент); log.info("Инициализировать конец {}", ProduceId); } } @Услуга общественный класс MessageService { частный окончательный MyCache myCache; частный окончательный StorageService StorageService; public MessageService (окончательный MyCache myCache, окончательный StorageService StorageService) { this.myCache = myCache; this.storageService = StorageService; } @Бин @Транзакционный общественный Consumer response1() { верните это::processResponse1; } @Бин @Транзакционный общественный Consumer response2() { верните это::processResponse2; } @Бин @Транзакционный общественный Consumer response3() { верните это::processResponse3; } частный недействительный процессResponse1 (окончательный ответ MyResponse1) { myCache.getCustomers().computeIfPresent(response.getProducerId(), (producerId, клиент) -> updateFromResponse1 (ответ, клиент)); } частный клиент updateFromResponse1 (окончательный ответ MyResponse1, конечный клиент клиента) { log.debug("Получен ответ 1 {}", ответ); // Обновление клиента с ответом процесс (клиент, StorageService:: saveCustomer); возврат клиента; } public voidprocess(конечный клиент-клиент, конечный Consumer customerUpdateCallback) { // Обработка клиента customerUpdateCallback.accept(клиент); } } @Услуга общественный класс StorageService { частный конечный CustomerRepository customerRepository; public StorageService (окончательный CustomerRepository customerRepository) { this.customerRepository = customerRepository; } public void saveCustomer(конечный клиент) { customerRepository.save(клиент); } }
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Ограничить клиентам hazelcast подключение к кластеру/экземпляру hazelcast.
Anonymous » » в форуме JAVA - 0 Ответы
- 19 Просмотры
-
Последнее сообщение Anonymous
-