如何决定是使用newCachedThreadPool还是newFixedThreadPool?

问题描述 投票:17回答:1

我正在开发一个项目,我需要确保每个线程都在特定范围内工作。例如:

NO_OF_THREADS: 2
NO_OF_TASKS: 10

如果number of threads is 2number of tasks is 10然后每个线程将执行10 tasks。这意味着2线程将做20 tasks

在实际场景中,这些数字(任务数和线程数)将非常高,因为它们都可以在我的代码中配置。

在上面的例子中,first thread应该使用1 and 10second thread之间的id应该使用11 and 20之间的id,如果有更多的线程。之后,每个线程将建立数据库连接,然后插入数据库。

所以我的下面的代码工作正常。

public static void main(String[] args) {

    final int noOfThreads = 2;
    final int noOfTasks = 10;

    //create thread pool with given size 
    ExecutorService service = Executors.newFixedThreadPool(noOfThreads);

    // queue some tasks 
    for (int i = 0, int nextId = 1; i < noOfThreads; i++, nextId += noOfTasks) {
        service.submit(new ThreadTask(nextId, noOfTasks));
    }
}

class ThreadTask implements Runnable {
    private final int id;
    private int noOfTasks;

    public ThreadTask(int nextId, int noOfTasks) {
        this.id = nextId;
        this.noOfTasks = noOfTasks;
    }

    public void run() {

    //make a database connection

        for (int i = id; i < id + noOfTasks; i++) {

        //insert into database
        }
    }
}

我的问题:-

我正在浏览互联网上的各种文章,我读到了关于newCachedThreadPool的文章。所以现在我想知道 - 我应该在我的代码中使用newFixedThreadPoolnewCachedThreadPool吗?目前我正在使用nexFixedThreadPool。我无法决定我应该选择哪些因素newCachedThreadPoolnewFixedThreadPool。所以这就是我发布我的场景的原因,我将对我的代码做些什么。

任何人都可以帮助我在这里选择什么?请详细解释我为什么我们选择哪些因素以便我能够理解这一点。我已经浏览过java文档,但无法决定我应该在这里选择什么。

谢谢您的帮助。

java multithreading executorservice
1个回答
24
投票

所以现在我想知道的是 - 我应该在我的代码中使用newFixedThreadPool或newCachedThreadPool吗?

引用Javadocs,newFixedThreadPool()

创建一个重用固定数量的线程的线程池...

这意味着如果你要求2个线程,它将启动2个线程并且永远不会启动3.另一方面,newCachedThreadPool()

创建一个根据需要创建新线程的线程池,但在它们可用时将重用以前构造的线程。

在您的情况下,如果您只有2个线程可以运行,则两者都可以正常工作,因为您只需要向池中提交2个作业。但是,如果您想一次提交所有20个作业,但一次只能运行2个作业,则应使用newFixedThreadPool(2)。如果您使用了缓存池,则20个作业中的每个将启动一个同时运行的线程,这可能不是最佳的,具体取决于您拥有多少CPU。

通常我在需要立即生成线程时使用newCachedThreadPool(),即使当前正在运行的所有线程都很忙。我最近在产生计时器任务时使用它。并发作业的数量是无关紧要的,因为我从来没有产生很多,但我希望它们在被请求时运行,我希望它们重新使用休眠线程。

当我想限制在任何一点运行的并发任务的数量以最大化性能而不是淹没我的服务器时,我使用了newFixedThreadPool()。例如,如果我从一个文件处理100k行,一次一行,我不希望每行开始一个新线程,但我想要一定程度的并发,所以我分配(例如)10个固定线程来运行任务直到池耗尽。

© www.soinside.com 2019 - 2024. All rights reserved.