java - 在 java 的多线程服务器中使用 try with 资源

标签 java multithreading sockets

我正在读一本书“java networking 4th edition”,在第 9 章中关于服务器套接字的内容解释了多线程服务器,其中每个客户端都由单个线程处理,它说了以下内容:

Example 9-3 deliberately does not use try-with-resources for the client sockets accepted by the server socket. This is because the client socket escapes from the try block into a separate thread. If you used try-with-resources, the main thread would close the socket as soon as it got to the end of the while loop, likely before the spawned thread had finished using it.

这是示例 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;
            }
        }
    }
}

我真的不明白为什么会这样,为什么主线程要关闭其他线程的套接字,是因为套接字对象是在主线程中创建的,并且在线程构造函数中提供了引用吗?

最佳答案

书上说的是他们选择这样做

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 block 时,它会在完成后立即关闭您放在括号 try(...) 中的任何内容。但是您不希望这种情况发生。 connection 套接字将保持打开状态,因为它将在已启动的 DaytimeThread 中使用。

关于java - 在 java 的多线程服务器中使用 try with 资源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52843618/

相关文章:

java - org.firebirdsql.jdbc.FBBlob 到文件

java - 如果构造函数没有任何返回类型,它如何返回?

java - 如何在多线程 Java 应用程序中安全地使用 OracleDriver.defaultConnection()?

java - 我的图书馆与我的 UNI 应用程序有多个连接

sockets - 云功能被杀死。错误: quota exceeded (Socket connections : per 100 seconds).大火计划

java - 异步 API 设计客户端

c - Linux/POSIX 等同于 Win32 的 CreateEvent、SetEvent、WaitForSingleObject

ajax - 是否可以将 socket.io 客户端与自定义 C# Web 服务器一起使用?

python - MRJob: socket.error: [Errno 104] 连接被对端重置

c - OpenMP - 临界区 + 缩减