В принципе, вам нужен реестр заблокированных потоков (или, что лучше, блокировок, на которых они ожидают), с ключом с некоторым идентификатором, который будет отправлен удаленной стороной.
Для асинхронной работы вы просто отправили сообщение и продолжили.
Для синхронной работы, после отправки сообщения, ваш отправляющий поток (или поток, который инициировал это) создает объект блокировки, добавляет его с некоторым ключом в реестр и затем ожидает блокировки до получения уведомления.
Поток чтения, когда он получает какой-либо ответ, ищет в реестре объект блокировки, добавляет к нему ответ и вызывает notify()
. Затем идет чтение следующего ввода.
Тяжелой работой здесь является правильная синхронизация, чтобы избежать мертвых блокировок, а также пропустить уведомление (потому что оно возвращается до того, как мы добавили себя в реестр).
Я сделал что-то подобное, когда реализовал протокол удаленного вызова метода для нашего Fencing -аплета. В принципе RMI работает так же, только без асинхронных сообщений.