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

2022-09-02 21:21:01

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

NO_OF_THREADS: 2
NO_OF_TASKS: 10

如果 和 则 每个线程将执行 .所以这意味着2线程将执行。number of threads is 2number of tasks is 1010 tasks20 tasks

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

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

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

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
        }
    }
}

我的问题:-

我正在浏览互联网上的各种文章,我读到了.所以现在我想知道的是 - 我应该在我的代码中使用还是在我的代码中?目前我正在使用.我无法决定我应该选择哪些因素或.这就是我发布我的场景的原因,我将如何处理我的代码。newCachedThreadPoolnewFixedThreadPoolnewCachedThreadPoolnexFixedThreadPoolnewCachedThreadPoolnewFixedThreadPool

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

感谢您的帮助。


答案 1

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

引用Javadocs的话,:newFixedThreadPool()

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

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

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

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

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

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


答案 2

我觉得它高度依赖于作业的类型,如果你有一个I / O绑定的函数,如果它是没有I / O的CPU密集型操作,请使用newCachedThreadPool(),使用另一个。