0

我正在编写客户端/套接字连接,并且正在使用 ThreadPools 来处理多个客户端。

在我的服务器启动后,我使用了几个资源。如果 f.ex.:服务器对客户端说它应该关闭,我想关闭所有这些,我想关闭所有东西。

我仍然编写了一个基本的关机功能:

public static void killClient() {
    try {
        threadpool.shutdown();
        in.close();//client input
        out.close();//client output
        socket.close();
    } catch(Exception e) {
        System.out.println("Client has been shutdown! " + e);
        e.printStackTrace();
    }
}

我的问题是:

如何确保一切都已正确关闭并且不再运行?

4

3 回答 3

1

如果您使用的是 Java7,那么您可以利用try-with-resources所有可关闭对象(如 Socket、Connection、Statement 等)的构造,一旦超出范围就会自动关闭它们。

于 2012-10-17T16:16:29.800 回答
1

如何确保一切都已正确关闭并且不再运行?

我已经回答了下面的具体问题。

我认为“关闭”你的课程比专注于关闭资源更重要。如果一个类(例如Client上面的类)包装了线程池和套接字等资源,那么它应该有一个close()方法(例如killClient()上面的)。如果服务器分叉一个客户端,那么它应该管理它们以便server.close()调用各种client.killClient()方法。

如果您对正确关闭各种类、try {} finally {}在任何地方使用块,您不应该担心未关闭的资源和挂起的线程。


这很难做到,并且没有针对所有资源类型的一揽子答案。这里有一些可能会有所帮助的想法。

  • 对于线程,您可以使用类似的东西Threads.getAllStackTraces()来显示剩下的线程。如果您在程序启动和完成时比较此列表,您应该能够看到剩下的内容。

  • 文件描述符要困难得多。如果您在 Linux 上运行,那么您可以查看/proc/self/fd目录以查看哪些描述符仍处于打开状态。再次比较开始和结束。您还可以查看应用程序中的OpenFileDescriptorCountJMX 变量( java.lang:type=OperatingSystem),但这只是给出了没有上下文的描述符的数量。

  • 没有简单的方法可以检测其他资源中的泄漏。您可以ResourceManager围绕它们包装一个类型类,从中“生成”和“释放”资源,但这需要编程支持。如果您在管理器之外创建资源,则没有简单的方法来检测泄漏。

  • 我为ORMLite测试所做的就是这种机制的一个例子。ORMLite 打开和关闭大量数据库连接,我想确保我的代码中没有泄露它们。我创建了一个围绕数据库连接的包装器,它会在创建时向管理器注册,并在关闭时取消注册。然后我可以确定assertTrue(connectionManager.isAllConnectionsClosed());。不确定这是否有帮助。

于 2012-10-17T16:17:33.690 回答
1

确保将所有 close() 和 shutdown() 方法放在单独的 try 块中,如果 in.close() 失败,则永远不会调用 out.close() 和 socket.close() 在代码中。

还要确保从 finally 块中调用方法 killclient()。

于 2012-10-17T16:19:52.253 回答