为什么实例化顺序似乎对 Java 中的输入和输出流很重要?
Why does order of instantiation seem to matter for input and output streams in Java?
我有以下有效代码(请假设主机名和端口已初始化为其正确的值,并且消息是可序列化的 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();
}
当我将 ObjectInputStream
的实例化移动到 ObjectOutputStream
实例化之后立即发生时,我的应用程序的执行无限期挂起:
//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();
}
我正在寻找一个很好的解释,说明为什么第二个示例始终锁定,而第一个示例似乎运行顺利。奇怪的是,如果我在第二个示例中在客户端和服务器上使用调试器(Eclipse 调试器),我会看到消息到达服务器,因此正在执行 writeObject()
调用。但是,在客户端中,调试器卡在 ObjectInputStream
.
的构造函数上
构造 ObjectOutputStream
将 header 写入流。构造一个 ObjectInputStream
读取它。如果两端都先构造ObjectInputStream
,就会出现死锁。
解决方案:先在两端构造ObjectOutputStream
,确保不会发生。
如果我们去阅读 API 文档 ObjectInputStream
constructor
重要部分:
This constructor will block until the corresponding ObjectOutputStream
has written and flushed the header.
我有以下有效代码(请假设主机名和端口已初始化为其正确的值,并且消息是可序列化的 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();
}
当我将 ObjectInputStream
的实例化移动到 ObjectOutputStream
实例化之后立即发生时,我的应用程序的执行无限期挂起:
//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();
}
我正在寻找一个很好的解释,说明为什么第二个示例始终锁定,而第一个示例似乎运行顺利。奇怪的是,如果我在第二个示例中在客户端和服务器上使用调试器(Eclipse 调试器),我会看到消息到达服务器,因此正在执行 writeObject()
调用。但是,在客户端中,调试器卡在 ObjectInputStream
.
构造 ObjectOutputStream
将 header 写入流。构造一个 ObjectInputStream
读取它。如果两端都先构造ObjectInputStream
,就会出现死锁。
解决方案:先在两端构造ObjectOutputStream
,确保不会发生。
如果我们去阅读 API 文档 ObjectInputStream
constructor
重要部分:
This constructor will block until the corresponding ObjectOutputStream has written and flushed the header.