У меня есть базовая асинхронная система запросов / ответов вне очереди, которую я хочу сделать синхронной. Запросы и ответы можно сопоставлять, помечая запросы уникальными идентификаторами, которые, в свою очередь, будут сопровождать соответствующие ответы.
Моя попытка сделать его синхронным использует два ConcurrentHashMap
s: один, который отображается из идентификаторов в результаты, и один, который сопоставляется с теми же идентификаторами в CountDownLatch
es. Код выполняется следующим образом при выполнении запроса:
public Result execute(Query query) throws InterruptedException {
int id = atomicInteger.incrementAndGet();
CountDownLatch latch = new CountDownLatch(1);
latchMap.put(id, latch);
query.executeAsyncWithId(id); // Probably returns before result is ready
try {
latch.await(); // Blocks until result is ready
return resultMap.remove(id);
} catch (InterruptedException e) {
latchMap.remove(id); // We are not waiting anymore
throw e;
}
}
И код для обработки входящего результата:
public void handleResult(Result result) {
int id = result.getId();
CountDownLatch latch = latchMap.remove(id);
if (latch == null) {
return; // Nobody wants result
}
resultMap.put(id, result);
latch.countDown();
}
Этот метод вызывается из потока, который считывает все входящие результаты из базовой системы (существует только один такой поток чтения).
Прежде всего, я не уверен в безопасности потоков, но для этого также нет необходимости использовать два HashMap
(особенно потому, что идентификаторы никогда не используются повторно). Есть идеи по улучшению?