gpt4 book ai didi

java - 线程池不调整大小

转载 作者:搜寻专家 更新时间:2023-10-31 20:10:05 31 4
gpt4 key购买 nike

我想创建一个缓存线程池,但它充当固定线程池。目前我有这段代码:

public class BackgroundProcesses {

public static void main(String[] args) throws InterruptedException, ExecutionException {
//ExecutorService threadPool2 = Executors.newCachedThreadPool();
ExecutorService threadPool = new ThreadPoolExecutor(2, 10, 180, TimeUnit.SECONDS, new LinkedBlockingQueue<>());
for (int i = 0; i < 800; i++) {
Callable<String> task = new Task();
threadPool.submit(task);
}
}
}

class Task implements Callable<String> {

@Override
public String call() throws Exception {
Thread.sleep(100);
System.out.println(Thread.currentThread().getName() + " is ready");
return "";
}
}

如果我运行代码,我会得到输出:

pool-1-thread-1 is ready
pool-1-thread-2 is ready
pool-1-thread-1 is ready
pool-1-thread-2 is ready
...

意味着只有 2 个线程在做所有的工作,并且没有新的工作线程被添加到池中。如果任务在队列中等待(在我的例子中最多 10 个),线程池不应该生成更多线程吗?

我不想使用 Executors.newCachedThreadPool() 因为它对最大线程几乎没有上限并且它有 corePoolSize 0。我想要一些线程随时准备就绪以获得更好的响应能力。

----- 编辑 1 -----

谢谢阿列克谢的回答。将容量设置为队列使其按预期运行,但现在我遇到了一个新问题。

后台任务的数量变化很大。大部分时间为 0,但短时间内最多可以执行 50 个并发任务。处理这个问题的有效方法是什么?请记住,大多数后台任务都是短期的 (< 1s),但也有一些长期任务 (> 1 分钟)。

如果我这样设置我的线程池:

ExecutorService threadPool = new ThreadPoolExecutor(2, 10, 180, TimeUnit.SECONDS, new LinkedBlockingQueue<>(10));

我很可能会在使用高峰时遇到 RejectedExecutionException。但是,如果我像这样设置线程池:

ExecutorService threadPool = new ThreadPoolExecutor(2, 10, 180, TimeUnit.SECONDS, new LinkedBlockingQueue<>(200));

然后不会添加新的工作线程,因为队列不会达到最大值。

CPU 至少有 4 个内核,所以我认为这很浪费。大多数时候根本没有任何后台任务(80% 的正常运行时间),所以在我看来保持固定的线程池也是一种浪费。

最佳答案

ThreadPoolExecutor Javadoc 说:

When a new task is submitted in method execute(Runnable), and fewer than corePoolSize threads are running, a new thread is created to handle the request, even if other worker threads are idle. If there are more than corePoolSize but less than maximumPoolSize threads running, a new thread will be created only if the queue is full

您的 LinkedBlockingQueue 永远不会满,因为它没有元素数量的上限。将 new LinkedBlockingQueue() 更改为 new LinkedBlockingQueue(10) 即可解决该问题。

关于java - 线程池不调整大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33752726/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com