Java 多个newSingleThreadExecutor与ExecutorService的newFixedThreadPool

Java 多个newSingleThreadExecutor与ExecutorService的newFixedThreadPool,java,multithreading,concurrency,threadpool,executorservice,Java,Multithreading,Concurrency,Threadpool,Executorservice,在我的应用程序中,我有4个不同的进程,它们永久运行,并有一些小的暂停 当前版本的代码在单独的老式线程中执行每个进程: Thread nlpAnalyzer = new Thread(() -> { // infine lop for auto restore in case of crash //noinspection InfiniteLoopStatement while (true) { try { // this m

在我的应用程序中,我有4个不同的进程,它们永久运行,并有一些小的暂停

当前版本的代码在单独的老式线程中执行每个进程:

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();
现在我想使用
ExecutorService
重构这段代码。为此,我至少可以使用两种方法:

  • newFixedThreadPool(numoproc)
  • numoproc*newSingleThreadExecutor()
我的问题:

  • 有什么理由让我更喜欢一个选项而不是另一个
  • 使用X个线程生成线程池或生成X
    newSingleThreadExecutor
    s,哪种方法更为可取
  • 每种方法的利弊

  • 假设每个任务都是一个无限循环,我会使用

    newCachedThreadPool();
    
    这将为每个需要它的任务创建一个线程(不再需要)

    使用单线程池的好处是,每个线程都可以单独关闭池,或者为每个线程指定一个名称,但如果不需要,这只是开销

    注意:您可以使用setName(“我的任务”)更改线程的名称,这对于调试/分析可能很有用

    使用ExecutorService的诀窍之一是,它捕获任何未捕获的异常/错误,并将其放置在返回的
    将来的
    对象中。通常情况下,这个
    未来
    会被丢弃,这意味着如果您的任务意外终止,它也可能会以静默方式完成


    我建议您在循环外执行try/catch(Throwable)并记录它,以便查看线程是否意外死亡。e、 g OutOfMemoryError

    除了关闭单个执行器之外,我看不出下面的选项有任何好处

    numOfProc * newSingleThreadExecutor()
    
    但是你有更多的选择。我更喜欢
    Executors
    中的以下三个选项之一

    newFixedThreadPool
    newCachedThreadPool
    newWorkStealingPool
    
    有关查询,请参阅以下SE问题:


    选项1更常见,开销最小。另一方面,您可以将无限循环中的代码重新编写为
    Runnable
    ,在运行时将自身作为执行器服务再次发布。这样,即使在单个线程上也可以运行多个任务。据我所知,我甚至可以将单独的线程名称分配到
    newFixedThreadPool
    ,而不仅仅是使用
    newSingleThreadExecutor
    。为X线程定义1
    newFixedThreadPool
    与X
    newSingleThreadExecutor
    s之间是否存在性能差异?@MikeB。您可以指定一个单独的线程名称,但不能根据任务的目的指定一个更有用的名称。我会做任何你觉得更清楚的事情,无论你选择了哪种解决方案,
    线程仍然可以工作。