Я не уверен, что правильно понимаю вопрос, но я обычно использую Future<T>
для такого рода задач.
Внутренне реализация Future<T>
использует ожидание и уведомлениеи все это, но сам интерфейс становится довольно чистым.
Future<Double> getTemperature(int id);
В своем коде связи вы можете сопоставить входящие сообщения с невыполненными фьючерсами.Если заказ гарантирован, вы можете сделать что-то вроде
class Something {
Map<Integer, Queue<Object>> requests;
synchronized Future<?> request(int id, Object data) {
MyFutureImpl future = new MyFuture();
requests.get(id).add(future);
serializeAndSend(id, data);
return future;
}
void serializeAndSend(id, data) {...}
synchronized void response(int id, Object data) {
MyFutureImpl future = requests.get(id).remove();
future.setValue(data); // This would fulfill the future, and any
// threads waiting in a get() will get the
// value and continue.
}
}
, где MyFutureImpl - это очень простая реализация в будущем.Я предполагаю, что есть коммуникационный поток, который вызывает response()
при получении пакета.Я также предполагаю, что serializeAndSend()
-функция обрабатывает запись клиенту или блокам, пока операция записи не может быть выполнена или передана потоку связи.
Использование сопоставления и очереди с поддержкой параллелизмаструктуры могут сделать некоторые synchronization
ненужными.Если для каждого идентификатора существует только один ожидающий вызов, очередь, разумеется, становится ненужной.