在java中创建无限循环的最佳方式是什么?
我有一个程序需要一个无限循环来保持运行。原因是我有一个SQS消费者,它会为每条消息分配一个线程,这是我的大部分逻辑所在。 不幸的是SQS使用者在另一个线程上内部运行,我无法控制,因为最好的实现是在主线程上运行它。在java中创建无限循环的最佳方式是什么?
我需要一种方法来停止程序退出,而消费者还活着,目前我使用一个线程睡眠while循环,但我记得有关这不是一个很好的解决方案。
当给定限制条件时,如果我没有办法改变SQSC消费者,那么最好的方法是保持程序活着。
更新:程序不打算停止过,在SQSConsumer起转10个线程从服务拉动的消息,我希望它继续这样做,直到我强迫程序中通过设置使用者退出。 isRunning()为false,或者通过强制程序以Ctrl + c结束。
例子:
SQSConsumer consumer = new SQSConsumer((event) -> {
callSomeLogicHere(event);
});
while (consumer.isRunning()) {
Thread.sleep(100);
}
使用CountdownLatch
:
-
创建一个最终的(或有效决赛)变量调用消费者面前:
CountdownLatch latch = new CountdownLatch(1);
-
在你拉姆达,用try/finally围绕对另一个逻辑的调用:
try { callSomeOtherLogic(); } finally { latch.countDown(); }
-
之后,要等待消费者来完成,等待锁:
latch.await();
请注意,这不是 “最好” 的方式要做到这一点,因为很少有客观上最好的方法;对于特定的应用来说只有最好的。
这就是说,这是更好比轮询,因为你不必继续检查其他线程是否已完成。如果你每100ms检查一次完成,而另一个线程需要至少10分钟才能完成,那么检查浪费很多;您可以使用您的CPU来完成更有价值的工作。您可以增加睡眠时间,以减少检查次数,但是您会增加完成和检测过程之间的预期额外等待时间(预期的额外等待时间为睡眠持续时间的一半)。
还应该注意的是,这里假定λ的完成表示消费者完成。这可能并非如此:
- 此方法假定lambda执行一次。这个假设可能不是真实的,例如,如果lambda被执行多次,或者可能永远不会。
- 即使只执行一次,消费者可能会在做更多的工作之后;在锁存器倒计时之后,您可能需要等待一段时间(或者甚至仍在轮询完成)。
总之,这不一定是这种情况下最好的,甚至是正确的方法。但是,有一整套并发实用程序 - java.util.concurrent
- 提供比简单轮询更好的功能,其中一些在此情况下可能适用。
多线程的目的被击败 – GurV
你可以提供关于你的SQSConsumer类的更多细节吗? – assylias