我有一个需要无限循环才能保持运行的程序。这样做的原因是我有一个SQS消费者,它将为每个消息分离一个线程,这就是我的大部分逻辑。 可悲的是,SQS消费者在另一个我无法控制的线程上内部运行,因为最好的实现是在主线程上运行它。
我需要一种方法来阻止程序在消费者活着时退出,目前我正在使用带有线程休眠的while循环,但我记得有些事情不是一个非常好的解决方案。
在给定限制我无法更改SQSConsumer的情况下,保持程序活着的最佳方法是什么。
更新:该程序无意停止,SQSConsumer将启动10个从服务中提取消息的线程,我希望它继续执行此操作,直到我强制程序退出将consumer.isRunning()设置为false,或强制程序以Ctrl + c终止。
示例:
SQSConsumer consumer = new SQSConsumer((event) -> {
callSomeLogicHere(event);
});
while (consumer.isRunning()) {
Thread.sleep(100);
}
答案 0 :(得分:3)
使用CountdownLatch
:
在调用使用者之前创建最终(或有效最终)变量:
CountdownLatch latch = new CountdownLatch(1);
在你的lambda中,用try / finally:
包围对其他逻辑的调用try {
callSomeOtherLogic();
} finally {
latch.countDown();
}
之后,如果您想等待消费者完成,请等待锁定:
latch.await();
请注意,这不是“最好”的方式,因为很少有客观的最佳方法;对于特定的应用程序,只有最好的。
据说,这比更好而不是轮询,因为你不必继续检查另一个线程是否已经完成。如果你每100ms检查一次完成,而另一个线程需要至少10分钟才能完成,那就浪费了大量的时间;你可以使用你的CPU做更有价值的工作。您可以增加睡眠时间以减少检查频率,但是然后增加完成和检测它的过程之间的预期额外等待时间(预期的额外等待时间是睡眠持续时间的一半)。
还应该注意,这假设lambda的完成表明消费者已完成。这可能不是真的:
简而言之,对于这种情况,这不一定是最好的,甚至是正确的方法。但是,有一整套并发实用程序 - java.util.concurrent
- 提供比简单轮询更好的功能,其中一些可能适用于这种情况。