0

我编写了一个在服务器上运行并监听某些端口的程序。由于大多数时候它无关紧要,所以我设置了一个线程来防止程序停止。

我的解决方案如下所示:

Thread mainThread = new Thread( new Runnable() {

            @Override
            public void run() {

                // run program continuously
                while ( true ) {
                    try {
                        // since we aren't doing anything, the thread can sleep
                        Thread.sleep( Long.MAX_VALUE );
                    }
                    catch ( InterruptedException e ) {

                        e.printStackTrace();
                    }
                }
            }
        } );

        mainThread.start();

我的问题是:常量Long.MAX_VALUE会不会有问题并导致错误?我想一直运行程序,所以我认为线程不需要做任何事情。到目前为止,最简单的解决方案是将其置于(非常非常深的)睡眠状态(毫秒值大致转换为 146.235.600 年)。

4

3 回答 3

1

只要有一个线程仍在运行或阻塞,多线程程序就会继续运行。您的程序不会因为原始线程退出而退出。您的程序可能有一个线程等待连接到端口,因此您不需要这样做。

于 2013-05-30T13:27:14.760 回答
0

罗伯特,如果我们阅读Thread类,我们会看到:

当 Java 虚拟机启动时,通常有一个非守护线程(通常调用某个指定类的名为 main 的方法)。Java 虚拟机继续执行线程,直到发生以下任一情况:

  • 已调用 Runtime 类的退出方法,并且安全管理器已允许进行退出操作。

  • 所有不是守护线程的线程都已经死亡,要么通过调用 run 方法返回,要么抛出传播到 run 方法之外的异常。

似乎您的应用程序在没有某种形式的“保持活动”机制的情况下总是会关闭,因为在您使用的框架中启动的线程都是daemon线程。

像您所做的那样,防止这种情况的简单方法是保持单个非守护线程处于活动状态并运行。

正如其他人所指出的那样,您发布的代码似乎有点“简单”,但从技术上讲并没有什么问题。

首先,我可以建议稍微简化一下 - 删除多余的使用new Runnable()并删除对e.printStackTrace().

关于Long.MAX_VALUE用作 Thread.sleep 的参数,正如其他人所评论的那样,这完全没问题。但是,使用某种常规的“健康检查”会更好,这样如果您使用的框架突然崩溃或退出,那么您的主线程也会如此。

这是我的建议:

    Thread mainThread = new Thread() {
        @Override
        public void run() {
            // check if application is healthy at regular intervals
            while ( myApplication.isHealthy() ) {
                try {
                    Thread.sleep( 30 );
                } catch ( InterruptedException e ) {
                    // ignore this, or log at DEBUG level
                }
            }
        }
    };
    mainThread.start();

关于改进机制或寻找另一种方法来做到这一点,我简要地研究了以下替代方案,但没有一个取得成果。

  1. BlockingQueue - 其他高级并发对象也可以无限期地“阻塞”,但它们也经常抛出InterruptedException并且肯定不如Thread.sleep

  2. ShutdownHook - 如果所有剩余线程都是守护进程,则关闭钩子不会阻止 jvm 停止(在这种情况下)

  3. setDaemon(false)使另一个线程成为非守护进程 - 虽然您可以轻松找到其他正在运行的线程,但一旦线程启动就无法调用它。

总之,鉴于这种情况,您所做的一切都很好——如果可以的话,您可以考虑定期检查您的框架是否仍然健康。

于 2013-05-30T13:51:13.117 回答
0

要直接回答这个问题,没有理由认为睡眠任何数量的(积极的)时间,包括, Long.MAX_VALUE,都会表现出与您预期的不同。

至于您是否需要这样做,我会回应其他人的评论,即从设计的角度来看,这可能不是最好的事情,并且很可能可以做出更好的架构决策来避免这种捏造(例如制作守护进程)如果您希望阻止应用程序退出,则线程非守护程序。)但是,从技术上讲,是的 - 线程应该在几个世纪的大部分时间里进入睡眠状态。

于 2013-05-30T13:33:07.763 回答