问题描述
在我的应用程序中,我有4个不同的进程,它们会在一些小的暂停时间内永久运行。 :
主题nlpAnalyzer = new Thread(() - > {
// infine lop for在失败的情况下自动恢复
// noinspection InfiniteLoopStatement
while(true){
try {
//此方法应该永久运行,暂停在内部实现
NLPAnalyzer。 analyzeNLP(dbCollection);
} catch(Exception e){
e.printStackTrace();
}
}
});
nlpAnalyzer.setName(im_nlpAnalyzer);
nlpAnalyzer.start();
现在我想使用 ExecutorService
。为了这样做,我可以使用至少两种方法:
-
newFixedThreadPool(numOfProc)
; -
numOfProc * newSingleThreadExecutor()
。
b $ b
我的问题:
- 我有什么理由?
- 更多接受生成X线程的线程池或生成X newSingleThreadExecutor?
- / li>
给定每个任务是一个无限循环,
newCachedThreadPool();
这将为每个需要它的任务创建一个线程
使用单线程池的好处是你可以单独关闭池,或给每个线程一个名字,但如果你不需要这个,它只是开销。
注意:您可以使用setName(我的任务)更改线程的名称,这对于调试/分析目的可能很有用。
使用ExecutorService的一个技巧是捕获任何未捕获的异常/错误,并将其放置在返回的 Future
对象中。通常这个未来
被丢弃,这意味着如果你的任务意外死亡,它也可能会默默做。
你做一个try / catch(Throwable)在循环外面并记录它,所以你可以看到线程是否意外死亡。例如OutOfMemoryError
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?
- 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
这篇关于多个newSingleThreadExecutor与ExecutorService的newFixedThreadPool的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!