Reputation: 21
I have a program that need an infinity loop to stay running. The reason for this is that i have a SQS consumer that will spin off a thread for each message it gets and this is where most of my logic is. Sadly is the SQS consumer internally running on another thread that i do not have control over, as the best implementation would have been to run it on the main thread.
I need a way to stop the program from exiting while the consumer is alive, currently am i using a while loop with a Thread sleep, but i remember something about this not being a very good solution.
What would the best way be to keep the program alive, when given the constrain that i have no way to change the SQSConsumer.
Update: The program is not intended to stop ever, the SQSConsumer will spin up 10 threads that is pulling messages from a service, i want it to keep doing this until i force the program to exit by setting consumer.isRunning() to false, or by forcing the program to terminate with a Ctrl+c.
Example:
SQSConsumer consumer = new SQSConsumer((event) -> {
callSomeLogicHere(event);
});
while (consumer.isRunning()) {
Thread.sleep(100);
}
Upvotes: 2
Views: 660
Reputation: 140318
Use a CountdownLatch
:
Create a final (or effectively final) variable before you call the consumer:
CountdownLatch latch = new CountdownLatch(1);
In your lambda, surround the call to the other logic with a try/finally:
try {
callSomeOtherLogic();
} finally {
latch.countDown();
}
Afterwards, where you want to wait for the consumer to finish, wait for the latch:
latch.await();
Note that this isn't the "best" way to do it, as there rarely is an objectively best approach in general; there is only a best with respect to a specific application.
With that said, this is better than polling, because you don't have to keep on checking whether the other thread has finished yet. If you are checking for completion every 100ms, and the other thread takes at least 10min to complete, that's a lot of wasted checking; you could be using your CPU to do more valuable work instead. You can increase the sleep time to do fewer checks less frequently, but you then increase the expected additional wait time between the process completing and detecting it (the expected additional wait is half the sleep duration).
It should also be noted that this assumes that completion of the lambda indicates completion of the consumer. This might not be true:
In short, this isn't necessarily the best, or even the right, approach for this case. However, there is an entire package of concurrent utilities - java.util.concurrent
- providing better functionality than simply polling, some of which may be appropriate in this case.
Upvotes: 3