Reputation: 999
I have the following code that works (please assume that hostname and port are initialized to their proper values, and that Message is a serializable class):
//Example 1 - everything works as expected
Message message = new Message();
try(Socket serverSocket = new Socket(hostname, port))
{
ObjectOutputStream outStream = new ObjectOutputStream(serverSocket.getOutputStream());
outStream.writeObject(message);
outStream.flush();
ObjectInputStream inStream = new ObjectInputStream(serverSocket.getInputStream());
Object response = inStream.readObject();
}
When I move the instantiation of the ObjectInputStream
to occur immediately after the ObjectOutputStream
instantiation, execution of my application hangs indefinitely:
//Example 2 - client locks up
Message message = new Message();
try(Socket serverSocket = new Socket(hostname, port))
{
ObjectOutputStream outStream = new ObjectOutputStream(serverSocket.getOutputStream());
ObjectInputStream inStream = new ObjectInputStream(serverSocket.getInputStream());
outStream.writeObject(message);
outStream.flush();
Object response = inStream.readObject();
}
I'm looking for a good explanation as to why the second example locks up consistently, and the first example seems to work without a hitch. Strangely, if I use a debugger (Eclipse debugger) on the client and server with this second example, I'm seeing the message make it through to the server, so the writeObject()
call is being executed. However, in the client, the debugger gets stuck on the constructor for the ObjectInputStream
.
Upvotes: 2
Views: 715
Reputation: 2085
If we go and have a read of the API docs for the ObjectInputStream
constructor
The important part:
This constructor will block until the corresponding ObjectOutputStream has written and flushed the header.
Upvotes: 4
Reputation: 310988
Constructing an ObjectOutputStream
writes a header to the stream. Constructing an ObjectInputStream
reads it. If both ends construct the ObjectInputStream
first, you will therefore get a deadlock.
Solution: construct the ObjectOutputStream
first, at both ends, to make sure it can't happen.
Upvotes: 1