Basically, you need a registry of blocked threads (or, better, the locks on which they are waiting), with a key with some identifier that will be sent by the remote side.
For an asynchronous operation, you just sent a message and continue.
For synchronous operation, after sending a message, the send thread (or the thread that initiated it) creates a lock object, adds it with some key to the registry, and then waits for a lock until notification.
The read stream, when it receives any response, looks at the lock object in the registry, adds a response to it, and calls notify() . He then reads the next input.
The hard work here is the correct synchronization to avoid deadlocks, as well as the lack of notification (because it returns before we add ourselves to the registry).
I did something similar when I applied the remote method invocation protocol for the Fencing- applet. Basically, RMI works the same way, just without asynchronous messages.
source share