In my application I have 4 distinct processes, which run permanently with some small pauses.
The current version of code executes each process in a separate old-school thread:
Thread nlpAnalyzer = new Thread(() -> {
// infine lop for auto restore in case of crash
//noinspection InfiniteLoopStatement
while (true) {
try {
// this method should run permanently, pauses implemented internally
NLPAnalyzer.analyzeNLP(dbCollection);
} catch (Exception e) {
e.printStackTrace();
}
}
});
nlpAnalyzer.setName("im_nlpAnalyzer");
nlpAnalyzer.start();
Now I would like to refactor this code with use of ExecutorService
. In order to do that I can use at least two approaches:
newFixedThreadPool(numOfProc)
;numOfProc * newSingleThreadExecutor()
.My questions:
newSingleThreadExecutor
s?In terms of resources, the newFixedThreadPool will keep all the threads running until they are explicitly terminated. In the newCachedThreadPool Threads that have not been used for sixty seconds are terminated and removed from the cache. Given this, the resource consumption will depend very much in the situation.
3. Fixed Thread Pool. As opposed to the cached thread pool, this one is using an unbounded queue with a fixed number of never-expiring threads. Therefore, instead of an ever-increasing number of threads, the fixed thread pool tries to execute incoming tasks with a fixed amount of threads.
The newFixedThreadPool() method of Executors class creates a thread pool that reuses a fixed number of threads operating off a shared unbounded queue. At any point, at most n Threads will be active processing tasks.
Below are some benefits: Executor service manage thread in asynchronous way. Use Future callable to get the return result after thread completion. Manage allocation of work to free thread and resale completed work from thread for assigning new work automatically.
Given each task is a infinite loop, what I would used is a
newCachedThreadPool();
This would create a thread for every task which needed it (and no more)
The benefit of using a single threaded pool each is you could shutdown the pool individually, or give each thread a name, but if you don't need this, it's just overhead.
Note: you can change the name of a thread with setName("My task") which might be useful for debugging/profiling purposes.
One of the tricks of using an ExecutorService is that it captures any uncaught exception/errors and places it in the Future
object returned. Often this Future
is discarded which means that if your task dies unexpectedly it might also do it silently.
I suggest you do a try/catch(Throwable) outside the loop and log it so you can see if the thread ever dies unexpectedly. e.g OutOfMemoryError
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With