java - 在java中创建无限循环的最佳方法是什么?

标签 java multithreading loops

我有一个程序需要无限循环才能保持运行。原因是我有一个 SQS 消费者,它将为它收到的每条消息分派(dispatch)一个线程,这就是我的大部分逻辑所在。 遗憾的是,SQS 消费者内部运行在我无法控制的另一个线程上,因为最好的实现是在主线程上运行它。

我需要一种方法来阻止程序在消费者存活时退出,目前我正在使用带有线程 sleep 的 while 循环,但我记得这不是一个很好的解决方案。

当我无法更改 SQSConsumer 时,保持程序运行的最佳方法是什么。

更新:该程序不会永远停止,SQSConsumer 将启动 10 个从服务中提取消息的线程,我希望它继续执行此操作,直到我强制程序退出通过将 Consumer.isRunning() 设置为 false,或者使用 Ctrl+c 强制程序终止。

示例:

SQSConsumer consumer = new SQSConsumer((event) -> {
    callSomeLogicHere(event);
});
while (consumer.isRunning()) {
    Thread.sleep(100);
}

最佳答案

使用CountdownLatch:

  • 在调用消费者之前创建一个最终(或实际上最终)变量:

    CountdownLatch latch = new CountdownLatch(1);
    
  • 在 lambda 中,用 try/finally 包围对其他逻辑的调用:

    try {
      callSomeOtherLogic();
    } finally {
      latch.countDown();
    }
    
  • 之后,在您想要等待消费者完成的地方,等待闩锁:

    latch.await();
    

请注意,这不是“最佳”方法,因为一般来说很少有客观的最佳方法;对于特定的应用程序来说,只有最好的。

话虽如此,这比轮询更好,因为您不必继续检查其他线程是否已完成。如果您每 100 毫秒检查一次是否完成,而另一个线程至少需要 10 分钟才能完成,那么就会浪费大量检查时间;您可以使用 CPU 来做更有值(value)的工作。您可以增加 sleep 时间以减少执行较少的检查的频率,但随后会增加进程完成和检测到进程之间的预期额外等待时间(预期的额外等待时间是 sleep 持续时间的一半)。

还应该注意的是,这假设 lambda 的完成表示消费者的完成。这可能不是真的:

  • 此方法假设 lambda 只执行一次。这个假设可能不成立,例如,如果 lambda 被执行多次,或者可能永远不会执行。
  • 即使只执行一次,消费者之后也可能会做更多的工作;在闩锁倒计时后,您可能需要等待一段时间(甚至仍然轮询完成)。

简而言之,对于这种情况,这不一定是最好的,甚至不是正确的方法。但是,有一整套并发实用程序 - java.util.concurrent - 提供比简单轮询更好的功能,其中一些功能可能适合这种情况。

关于java - 在java中创建无限循环的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41001318/

相关文章:

python - 在 Python 的多处理程序中打开和关闭循环

c# - C# 中的触发事件会阻止当前线程执行吗?

C程序While循环问题

linux - 在 ftp 命令内循环

Java:如何将 .txt 文件中的单独文本行保存到字符串数组中?

java - 将 curl 命令翻译成 Java/Android

java - 线性布局不可见/重叠

java - 如何在 Volley 或 Retrofit 中接收确认?

python - 使用标准输出同时写入多行

php - 基于 <select> PHP/Mysql 更改输入值