赞
踩
在 线程池——核心线程数、阻塞队列、最大线程数之间的关系 中我们从运行流程层面了解了线程池处理任务的顺序。
在 ThreadPoolExecutor 的基础变量 ctl 、 runState 和 workerCount 中,我们对线程中比较关键的几个核心变量和方法进行了介绍。
这两篇文为本文的学习奠定了基础。
void execute(Runnable command);
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class TestA { static ExecutorService executorService = Executors.newFixedThreadPool(2); public static void main(String[] args) { executorService.execute(()->{ System.out.println("aaa"); System.out.println("aaa2"); }); executorService.submit(()->{ System.out.println("bbb"); System.out.println("bbb2"); }); executorService.shutdown(); } }
execute 方法用于向线程池提交任务。
查看 submit 的源码可以发现,submit 的底层调用的也是 execute
public Future<?> submit(Runnable task) {
if (task == null) throw new NullPointerException();
RunnableFuture<Void> ftask = newTaskFor(task, null);
//调用了 execute
execute(ftask);
return ftask;
}
有了之前两篇文档的铺垫,下面这段代码的逻辑就很清晰了
注意 if( ! isRunning(recheck) && remove(command) ) 会先判断 ! isRunning(recheck) ,如果线程池不处于运行状态,会执行 remove(command)
public void execute(Runnable command) { if (command == null) throw new NullPointerException(); 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(); // 双重检查(! isRunning(recheck)) && remove(command) if (! isRunning(recheck) && remove(command)) reject(command); else if (workerCountOf(recheck) == 0) addWorker(null, false); } else if (!addWorker(command, false)) reject(command); }
我们用流程图的形式进行展示
默认不会,可以配置
/**
* If false (default), core threads stay alive even when idle.
* If true, core threads use keepAliveTime to time out waiting
* for work.
*/
private volatile boolean allowCoreThreadTimeOut;
/**
* Set containing all worker threads in pool. Accessed only when
* holding mainLock.
*/
private final HashSet<Worker> workers = new HashSet<Worker>();
t.start()
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。