I created an ObjectInputSteam
and ObjectOutputStream
on a blocking SocketChannel
and am trying to read and write concurrently. My code is something like this:
socketChannel = SocketChannel.open(destNode);
objectOutputStream = new ObjectOutputStream(Channels.newOutputStream(socketChannel));
objectInputStream = new ObjectInputStream(Channels.newInputStream(socketChannel));
Thread replyThread = new Thread("SendRunnable-ReplyThread") {
@Override
public void run() {
try {
byte reply = objectInputStream.readByte();//(A)
//..process reply
} catch (Throwable e) {
logger.warn("Problem reading receive reply.", e);
}
}
};
replyThread.start();
objectOutputStream.writeObject(someObject);//(B)
//..more writing
Problem is the write at line (B) blocks until the read at line (A) completes (blocks on the object returned by SelectableChannel#blockingLock()
). But app logic dictates that the read will not complete until all the writes complete, so we have an effective deadlock.
SocketChannel
javadocs say that concurrent reads and writes are supported.
I experienced no such problem when I tried a regular Socket solution:
Socket socket = new Socket();
socket.connect(destNode);
final OutputStream outputStream = socket.getOutputStream();
objectOutputStream = new ObjectOutputStream(outputStream);
objectInputStream = new ObjectInputStream(socket.getInputStream());
However, then I cannot take advantage of the performance benefits of FileChannel#transferTo(...)