首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在java中对多线程服务器中的资源使用try

在java中对多线程服务器中的资源使用try
EN

Stack Overflow用户
提问于 2018-10-17 04:30:24
回答 2查看 887关注 0票数 3

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

Example 9-3故意不对服务器套接字接受的客户端套接字使用try-with-resources。这是因为客户端套接字从try块转义到一个单独的线程中。如果使用try-with-resources,主线程会在到达while循环的末尾时立即关闭套接字,很可能是在派生的线程使用完套接字之前。

下面是示例9-3

代码语言:javascript
复制
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;
            }
        }
    }
}

}

我真的不明白为什么会发生这种情况,为什么主线程要从另一个线程关闭套接字,是因为套接字对象是在主线程中创建的,而引用是在线程构造函数中提供的吗?

EN

回答 2

Stack Overflow用户

发布于 2018-10-17 04:38:03

书中所说的是他们选择这样做

代码语言:javascript
复制
try {
    Socket connection = server.accept();
    Thread task = new DaytimeThread(connection);
    task.start();
} catch (IOException ex) {}

而不是

代码语言:javascript
复制
try(Socket connection = server.accept()) {
    Thread task = new DaytimeThread(connection);
    task.start();
} catch (IOException ex) {}

因为在使用try-with-resources块时,它会在完成后立即关闭您放在圆括号try(...)中的所有内容。但您不希望这种情况发生。connection套接字应该保持打开状态,因为它将在已启动的DaytimeThread中使用。

票数 9
EN

Stack Overflow用户

发布于 2018-10-17 04:39:44

主线程不想关闭资源,因为派生的线程异步执行

try中,task.start()开始执行线程,但不等待线程完成。因此,main方法有可能(甚至很可能)在DaytimeThread.run()结束之前到达其try的末尾。

如果main方法的try是try-with-resources,连接将在此时关闭。然后,当DaytimeThread继续在另一个线程中执行其工作时,它将在该连接关闭后尝试使用该连接。

但要回答你的实际问题:

为什么主线程要从另一个线程关闭套接字

它不是来自另一个线程的套接字。实际上,的主方法接受套接字连接,然后将其提供给DaytimeThread

通常,负责获取可关闭资源的实体也应该负责关闭它。实现这一点的简单方法是使用try- with -resources。但是,这一原则不能应用于这种设计,因为在主线程使用完资源之后,线程可能需要该资源。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52843618

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档