gpt4 book ai didi

java - ThreadPoolExecutor.execute(Runnable command) 何时创建新线程

转载 作者:行者123 更新时间:2023-11-30 01:49:27 26 4
gpt4 key购买 nike

我正在阅读ThreadPoolExecutor.java的源代码,对于execute方法如下:

    public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
/*
* Proceed in 3 steps:
*
* 1. If fewer than corePoolSize threads are running, try to
* start a new thread with the given command as its first
* task. The call to addWorker atomically checks runState and
* workerCount, and so prevents false alarms that would add
* threads when it shouldn't, by returning false.
*
* 2. If a task can be successfully queued, then we still need
* to double-check whether we should have added a thread
* (because existing ones died since last checking) or that
* the pool shut down since entry into this method. So we
* recheck state and if necessary roll back the enqueuing if
* stopped, or start a new thread if there are none.
*
* 3. If we cannot queue task, then we try to add a new
* thread. If it fails, we know we are shut down or saturated
* and so reject the task.
*/
int c = ctl.get();
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))
return;
c = ctl.get();
}
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ctl.get();
if (! isRunning(recheck) && remove(command))
reject(command);
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
else if (!addWorker(command, false))
reject(command);
}

假设线程池有 2 个核心线程,并将最大池大小设置为 4。

我能理解代码if (workerCountOf(c) < corePoolSize) { addWorkder(..) } ,这意味着如果当前核心线程数小于核心轮询大小,则只需创建一个新线程来处理可运行命令。

我无法理解的是,如果我们已经打电话 execute(runnable)两次了,每次都需要很长时间才能完成,所以现在还很忙,现在我们正在打电话第三次。

这段代码会做什么?我认为代码是 if (isRunning(c) && workQueue.offer(command)) {因此该命令被添加到工作队列中。但是,我不明白这第三个命令将由哪个线程执行。根据代码else if (workerCountOf(recheck) == 0) ,我认为worker数量应该是2,因为我们已经添加了两个worker。

所以我的问题是什么时候添加第三个 worker ?

--编辑--

我的测试代码:


public class ThreadPoolExecutorTest {
public static void main(String[] args) {
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
2,
4,
60,
TimeUnit.SECONDS,
new ArrayBlockingQueue<>(4)
);

threadPoolExecutor.execute(new Command("A"));
threadPoolExecutor.execute(new Command("B"));
threadPoolExecutor.execute(new Command("C"));

}

static class Command implements Runnable {
private String task;
Command(String task) {
this.task = task;
}

@Override
public void run() {
try {
Thread.sleep(1000 * 10);
System.out.println(new Date() + " - " + Thread.currentThread().getName() + " : " + task);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

它打印:

Thu Jun 13 17:44:30 CST 2019 - pool-1-thread-1 : A
Thu Jun 13 17:44:30 CST 2019 - pool-1-thread-2 : B
Thu Jun 13 17:44:40 CST 2019 - pool-1-thread-1 : C

通过测试代码,我预计核心工作人员会持续忙碌 10 秒,因此当 execute("C") 时我想打“核心 worker 忙,将添加第3个 worker ”的情况,但似乎没有第3个 worker ?抱歉,出了什么问题?

谢谢。

最佳答案

I want to hit the case 'core workers are busy and the 3rd worker will be added'

那么你还必须填满队列。

Javadoc 说:

When a new task is submitted in method execute(java.lang.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.

关于java - ThreadPoolExecutor.execute(Runnable command) 何时创建新线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56577264/

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