使用Thread.sleep和CountDownLatch来保持主线程运行的区别

4

我希望我的主线程一直运行,因为我有一些监听器将在另一个线程中监听请求/消息,我不希望我的主线程死亡。

哪个更好?

CountDownLatch计数器

public static void main(String[] args) throws InterruptedException {

    startListener();
    CountDownLatch latch = new CountDownLatch(1);
    latch.await();

}

Or While with sleep

public static void main(String[] args) throws InterruptedException {

    startListener();
    while (true){
        Thread.sleep(1000);
    }

}

主线程如何知道何时恢复/继续? - ernest_k
听者到底是干什么的?在两种选择中,倒计时门闩更好,但可能有更适合的结构。 - daniu
@daniu:监听器将是一个JMS监听器,将在整天内监听消息,除非我们停止这个过程。 - Sujeet
@Sujeet 我了解这是关于主线程如何被通知您的监听器完成工作的。您能展示一下 startListeners() 或任何必须在主线程终止之前完成的代码吗? - ernest_k
CountDownLatch.await 是一种更复杂的机制,它会等待直到计数器减为0,而 Thread.sleep 很少是一个好决定,特别是当它是重复的时候。这两种情况都不好,没有办法停止它们(前者需要在 startListener 中传递 latch,后者需要引用主线程才能中断它)。 - Andrew Tobilko
显示剩余2条评论
3个回答

4
假设您的监听线程是非守护线程,您可以让主线程结束。只要有非守护线程在执行,JVM 就会继续运行。
如果您计划实现优雅的关闭,则CountDownLatch将是更好的解决方案。您可以触发该门闩并通过执行清理逻辑让主线程完成。考虑应用程序如何关闭,例如当监听器正在从队列中读取消息时,您收到一个SIGTERM信号,那么怎么办呢?

谢谢,将其设置为非守护进程可以正常工作!将其设置为非守护进程是否会有任何影响?我们需要注意其他方面吗? - Sujeet
@Sujeet,你可以查看Spring的DefaultMessageListenerContainer,了解从JMS读取时面临的挑战。 - Karol Dowbecki
唯一的区别是,如果该线程仍然存在,JVM 将继续运行。 - Roee Gavirel

2

没有。

首先,如果startListener()创建了一个新线程,即使主线程结束,应用程序仍将保持运行。只要有至少一个非守护线程正在运行,就是这样的。(这与C / C ++不同,在那里应用程序随着主线程的结束而结束,您可能会混淆)。

关于您提出的选项。两者都将创建一个无法退出的无限循环,这可能不是最佳实践。但是如果必须选择其中之一,则latch更好,因为它不会每秒消耗CPU。

最初的回答。


0

这两种提议的方法都可行,但我建议使用主线程同步处理传入消息。这样消息将会更快地处理,并且需要更少的资源(线程)。请参见同步接收消息的简单示例。因此不需要监听器。


实际上,我有多个不同类型的监听器,它们在自己的线程中监听不同的主题。因此,在这种情况下,我认为单个主线程监听可能不是一个好主意。 - Sujeet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接