我正在读一本名为"java网络第4版“的书,在第9章关于服务器套接字的书中,我解释了多线程服务器,其中每个客户端都是由单个线程处理的,它说了以下内容:
Example 9-3故意不对服务器套接字接受的客户端套接字使用try-with-resources。这是因为客户端套接字从try块转义到一个单独的线程中。如果使用try-with-resources,主线程会在到达while循环的末尾时立即关闭套接字,很可能是在派生的线程使用完套接字之前。
下面是示例9-3
import java.net.*;
import java.io.*;
import java.util.Date;
public class MultithreadedDaytimeServer {
public final static int PORT = 13;
public static void main(String[] args) {
try (ServerSocket server = new ServerSocket(PORT)) {
while (true) {
try {
Socket connection = server.accept();
Thread task = new DaytimeThread(connection);
task.start();
} catch (IOException ex) {}
}
} catch (IOException ex) {
System.err.println("Couldn't start server");
}
}
private static class DaytimeThread extends Thread {
private Socket connection;
DaytimeThread(Socket connection) {
this.connection = connection;
}
@Override
public void run() {
try {
Writer out = new OutputStreamWriter(connection.getOutputStream());
Date now = new Date();
out.write(now.toString() +"\r\n");
out.flush();
} catch (IOException ex) {
System.err.println(ex);
} finally {
try {
connection.close();
} catch (IOException e) {
// ignore;
}
}
}
}}
我真的不明白为什么会发生这种情况,为什么主线程要从另一个线程关闭套接字,是因为套接字对象是在主线程中创建的,而引用是在线程构造函数中提供的吗?
发布于 2018-10-17 04:38:03
书中所说的是他们选择这样做
try {
Socket connection = server.accept();
Thread task = new DaytimeThread(connection);
task.start();
} catch (IOException ex) {}而不是
try(Socket connection = server.accept()) {
Thread task = new DaytimeThread(connection);
task.start();
} catch (IOException ex) {}因为在使用try-with-resources块时,它会在完成后立即关闭您放在圆括号try(...)中的所有内容。但您不希望这种情况发生。connection套接字应该保持打开状态,因为它将在已启动的DaytimeThread中使用。
发布于 2018-10-17 04:39:44
主线程不想关闭资源,因为派生的线程异步执行。
在try中,task.start()开始执行线程,但不等待线程完成。因此,main方法有可能(甚至很可能)在DaytimeThread.run()结束之前到达其try的末尾。
如果main方法的try是try-with-resources,连接将在此时关闭。然后,当DaytimeThread继续在另一个线程中执行其工作时,它将在该连接关闭后尝试使用该连接。
但要回答你的实际问题:
为什么主线程要从另一个线程关闭套接字
它不是来自另一个线程的套接字。实际上,的主方法接受套接字连接,然后将其提供给DaytimeThread。
通常,负责获取可关闭资源的实体也应该负责关闭它。实现这一点的简单方法是使用try- with -resources。但是,这一原则不能应用于这种设计,因为在主线程使用完资源之后,线程可能需要该资源。
https://stackoverflow.com/questions/52843618
复制相似问题