【问题标题】:What is the best way to create an infinite loop in java?在java中创建无限循环的最佳方法是什么?
【发布时间】:2017-04-21 10:38:50
【问题描述】:

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

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

在我无法更改 SQSConsumer 的约束条件下,保持程序运行的最佳方法是什么。

更新:该程序不打算停止,SQSConsumer 将启动 10 个线程从服务中提取消息,我希望它继续这样做,直到我强制程序退出通过将 consumer.isRunning() 设置为 false,或者通过 Ctrl+c 强制程序终止。

例子:

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

【问题讨论】:

  • 多线程的目的被打败了
  • 你能提供更多关于你的 SQSConsumer 类的细节吗?

标签: java multithreading loops


【解决方案1】:

使用CountdownLatch

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

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

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

    latch.await();
    

请注意,这不是“最好”的方法,因为通常很少有客观上最好的方法;对于特定的应用,只有最好的。

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

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

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

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

【讨论】:

  • 为什么这是最好的方法?
  • 我已经用更多信息更新了我的第一篇文章。我认为这不会起作用,因为 lambda 函数旨在被称为“无限次”
猜你喜欢
  • 2020-09-22
  • 2021-08-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-08
  • 1970-01-01
  • 2011-11-15
  • 2015-04-06
相关资源
最近更新 更多