Java:正确关闭多个线程

时间:2013-02-13 23:53:43

标签: java multithreading sockets

我正在制作一个简单的服务器,它将产生多个线程来处理多个客户端。我想知道在服务器终止时关闭和关闭所有各种流和线程的正确方法。

我添加了一个shutdownHook,它运行一个告诉服务器关闭的方法。反过来,服务器向它打开的所有线程广播关闭调用,这会将每个线程中的“isClosed”布尔值设置为true。

我期待的是每个线程在到达run()方法的末尾并再次循环时,点击while(!isClosed)条件,从而通过关闭所有正确的套接字/流来正确终止自身返回。

但是,我不知道这是否会正确关闭所有内容,因为程序应在shutdownhook完成后终止。它很早就完成,因为它所做的就是传播结束消息。这是否意味着某些线程没有足够的时间来正确关闭?

如果是这样,最好的方法是让shutdownhook手动关闭每个线程,确保它们已经关闭,然后返回吗?

4 个答案:

答案 0 :(得分:0)

使用ExecutorService是现代的做法。它需要从代码中获取大量繁琐的内容。

Here是一个很好的起点。

答案 1 :(得分:0)

如果服务器终止,那么线程可能没有足够的时间正确终止是正确的。但是,根据您要做的事情,这可能是也可能不是问题。如果不需要清理工作,那么您可能不需要担心它,因为线程突然终止将不会引起任何问题。

但是,如果需要进行清理工作(例如写入数据库),那么您还需要其他东西。执行此操作(在Java中)的最佳方法是使用Executor / ExecutorService和相关项(http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/Executors.html)。这些问题得到了很好的解决,而且你得到了一些不错的免费赠品,比如线程池管理,这样缩放就容易多了。如果您为每个客户端生成一个新线程,那么当您尝试稍后进行扩展时会出现大问题,例如,因为您无法每分钟创建一百万个线程。

如果您习惯使用原始线程,使用Excecutor的东西有点调整,但值得研究。祝你好运!

答案 2 :(得分:0)

在此循环中,shutdownHook发生得太晚,无法使用。它预计会很快完成并且JVM已经停止运行,如果它们是守护进程,它可以使用现有的线程。

我只想在15-30秒的连接线程上设置读取超时。如果超时发生(SocketTimeoutException),请关闭套接字并退出线程。当然,客户必须应对掉线,但他们必须这样做。然后,当您想要关闭时,只需停止接受新连接(例如,关闭ServerSocket并使其接受线程正确应对所导致的异常)。当所有现有连接线程都退出时,JVM将退出,这应该不会超过超时时间加上最长事务的长度。确保连接线程不是守护进程。

如果您不介意客户在交易中期被切断,请致电System.exit().

答案 3 :(得分:0)

您是否考虑过制作线程后台程序线程。 只需添加t.setdaemon(true);在调用线程的start方法之前。 如果在程序结束时应该结束这些线程,那么一旦所有其他非守护程序线程结束,守护程序将终止它们。 在线程池中使用的线程是应该是守护进程的线程的好例子。 我真的认为它对你有用。