我创建了一个ObjectInputSteam
和ObjectOutputStream
上形成阻挡SocketChannel
,我试图读取并同时写.我的代码是这样的:
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
问题是在行(B)块处写入,直到第(A)行的读取完成(返回的对象上的块SelectableChannel#blockingLock()
).但app逻辑规定在完成所有写操作之前读取不会完成,因此我们有一个有效的死锁.
SocketChannel
javadocs说支持并发读写.
当我尝试常规的Socket解决方案时,我没有遇到过这样的问题:
Socket socket = new Socket(); socket.connect(destNode); final OutputStream outputStream = socket.getOutputStream(); objectOutputStream = new ObjectOutputStream(outputStream); objectInputStream = new ObjectInputStream(socket.getInputStream());
但是,那时我无法利用性能优势 FileChannel#transferTo(...)
这似乎是一个错误java.nio.channels.Channels
(感谢Tom Hawtin;下次将其发布为答案)。这里描述了一个很好的描述和解决方法(实际上是Tom列出的错误的重复):
我测试了解决方法,它可以工作。