文章目录
前言
在 线程池——核心线程数、阻塞队列、最大线程数之间的关系 中我们从运行流程层面了解了线程池处理任务的顺序。
在 ThreadPoolExecutor 的基础变量 ctl 、 runState 和 workerCount 中,我们对线程中比较关键的几个核心变量和方法进行了介绍。
这两篇文为本文的学习奠定了基础。
接口 Executor.execute(Runnable command);
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();
}
}
ThreadPoolExecutor.execute
execute 方法用于向线程池提交任务。
ThreadPoolExecutor.submit
查看 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;
}
ThreadPoolExecutor.execute 源码
有了之前两篇文档的铺垫,下面这段代码的逻辑就很清晰了
注意 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>();
线程池如何执行 task
t.start()