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:
- Is there any reason why I should prefer one option over another?
- What is more accepted to generate a thread pool with X threads or generate X
newSingleThreadExecutor
s?
- Pro et contra of each of the approach?
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
I don't see any benefit for below option except shutting down individual executor.
numOfProc * newSingleThreadExecutor()
But you have more options. I prefer one of below three options from Executors
.
newFixedThreadPool
newCachedThreadPool
newWorkStealingPool
Refer to below SE questions for relevant queries :
Java's Fork/Join vs ExecutorService - when to use which?
How to properly use Java Executor?
Difference between Executors.newFixedThreadPool(1) and Executors.newSingleThreadExecutor()