Java: Sind gleichzeitige Lese- und Schreibvorgänge auf einem blockierenden SocketChannel über Object (In | Out) putStreams möglich?
Ich habe eine erstelltObjectInputSteam
undObjectOutputStream
auf eine SperrungSocketChannel
und versuche gleichzeitig zu lesen und zu schreiben. Mein Code sieht ungefähr so aus:
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 ist, dass der Schreibzugriff auf Zeile (B) so lange blockiert wird, bis der Lesezugriff auf Zeile (A) abgeschlossen ist (Blöcke auf dem von zurückgegebenen Objekt)SelectableChannel#blockingLock()
). Die App-Logik schreibt jedoch vor, dass der Lesevorgang erst abgeschlossen wird, wenn alle Schreibvorgänge abgeschlossen sind, sodass ein effektiver Deadlock vorliegt.
SocketChannel
Javadocs sagen, dass gleichzeitige Lese- und Schreibvorgänge unterstützt werden.
Ich hatte kein solches Problem, als ich eine normale Socket-Lösung ausprobierte:
Socket socket = new Socket();
socket.connect(destNode);
final OutputStream outputStream = socket.getOutputStream();
objectOutputStream = new ObjectOutputStream(outputStream);
objectInputStream = new ObjectInputStream(socket.getInputStream());
Dann kann ich jedoch die Leistungsvorteile von nicht nutzenFileChannel#transferTo(...)