2016-12-06 53 views
1

我有一个程序需要一个无限循环来保持运行。原因是我有一个SQS消费者,它会为每条消息分配一个线程,这是我的大部分逻辑所在。 不幸的是SQS使用者在另一个线程上内部运行,我无法控制,因为最好的实现是在主线程上运行它。在java中创建无限循环的最佳方式是什么?

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

当给定限制条件时,如果我没有办法改变SQSC消费者,那么最好的方法是保持程序活着。

更新:程序不打算停止过,在SQSConsumer起转10个线程从服务拉动的消息,我希望它继续这样做,直到我强迫程序中通过设置使用者退出。 isRunning()为false,或者通过强制程序以Ctrl + c结束。

例子:

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

多线程的目的被击败 – GurV

+0

你可以提供关于你的SQSConsumer类的更多细节吗? – assylias

回答

3

使用CountdownLatch

  • 创建一个最终的(或有效决赛)变量调用消费者面前:

    CountdownLatch latch = new CountdownLatch(1); 
    
  • 在你拉姆达,用try/finally围绕对另一个逻辑的调用:

    try { 
        callSomeOtherLogic(); 
    } finally { 
        latch.countDown(); 
    } 
    
  • 之后,要等待消费者来完成,等待锁:

    latch.await(); 
    

请注意,这不是 “最好” 的方式要做到这一点,因为很少有客观上最好的方法;对于特定的应用来说只有最好的。

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

还应该注意的是,这里假定λ的完成表示消费者完成。这可能并非如此:

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

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

+0

为什么这是最好的方式? – abbath

+0

我已经更新了我的第一篇文章,提供了更多信息。我不认为这会起作用,因为lambda函数被称为“无限次” – Androme

相关问题