当前位置:实例文章 » 其他实例» [文章]【并发专题】线程池ThreadPoolExecutorl底层原理源码分析

【并发专题】线程池ThreadPoolExecutorl底层原理源码分析

发布人:shili8 发布时间:2025-03-04 11:24 阅读次数:0

**并发专题: 线程池ThreadPoolExecutor底层原理源码分析**

在Java世界中,线程池是实现高性能并发编程的关键组件之一。ThreadPoolExecutor是Java.util.concurrent包中的一个重要类,它提供了一个线程池来管理和执行任务。下面我们将深入探讨ThreadPoolExecutor的底层原理和源码分析。

**一、线程池的基本概念**

线程池是一种资源共享机制,允许多个线程共用同一个线程对象。线程池通过维护一个线程集合来实现这一点,每当有任务需要执行时,就从线程集合中取出一个可用的线程来执行该任务。

**二、ThreadPoolExecutor的构造**

ThreadPoolExecutor的构造函数如下所示:

javapublic ThreadPoolExecutor(int corePoolSize,
 int maximumPoolSize,
 long keepAliveTime,
 TimeUnit unit,
 BlockingQueue workQueue) {
 this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
 Executors.defaultThreadFactory(), (RejectedExecutionHandler) new ThreadPoolExecutor.AbortPolicy());
}

从构造函数中可以看出,ThreadPoolExecutor需要以下参数:

* `corePoolSize`:线程池的核心大小,即线程集合中的线程数量。
* `maximumPoolSize`:线程池的最大大小,即线程集合中的线程数量上限。
* `keepAliveTime`:线程集合中线程的存活时间,单位为`unit`指定的时间单位。
* `workQueue`:任务队列,用于存放等待执行的任务。
* `threadFactory`:线程工厂,用于创建新线程。
* `rejectedExecutionHandler`:拒绝策略,用于处理无法添加到线程集合中的任务。

**三、线程池的工作流程**

下面是线程池的工作流程:

1. **任务提交**:当有任务需要执行时,首先会尝试将该任务添加到线程集合中。如果线程集合中有可用的线程,则会从线程集合中取出一个线程来执行该任务。
2. **线程创建**:如果线程集合中没有可用的线程,则会创建新线程并添加到线程集合中。
3. **任务执行**:当线程集合中有可用的线程时,会从线程集合中取出一个线程来执行该任务。
4. **任务完成**:当任务执行完毕后,线程将返回线程集合中等待下一次任务的状态。

**四、源码分析**

下面是ThreadPoolExecutor的关键方法源码分析:

### `execute(Runnable command)`

javapublic void execute(Runnable command) {
 if (command == null)
 throw new NullPointerException();
 int c = ctl.get();
 if (workerCountOf(c) < corePoolSize) {
 if (addWorker(command, c)) return;
 c = ctl.get();
 }
 if (isRunning(c) && workerCountOf(c) < maximumPoolSize &&
 !surplusPredicates().anyMatch(surplus -> surplus.test(command))) {
 int reints = enlargedPoolSize(c);
 if (workerCountOf(c) >= reints)
 addWorker(command, c);
 else if (ctl.compareAndSet(c, c, c | WORKER_START))
 workerStart(command);
 } else if (!surplusPredicates().anyMatch(surplus -> surplus.test(command))) {
 rejectedExecution(command, this);
 }
}


从源码中可以看出,`execute(Runnable command)`方法首先会尝试将任务添加到线程集合中。如果线程集合中有可用的线程,则会从线程集合中取出一个线程来执行该任务。

### `addWorker(Runnable firstTask, boolean core)
`javaprivate boolean addWorker(Runnable firstTask, boolean core) {
 Thread t;
 final ReentrantLock mainLock = this.mainLock;
 mainLock.lock();
 try {
 int c = ctl.get();
 if (workerCountOf(c) ==0)
 t = getNewThread(core);
 else {
 t = addWorkerWaiter(firstTask, core);
 }
 } finally {
 mainLock.unlock();
 }
 if (t == null)
 return false;
 Workers.wakeOne();
 Thread.startThread(t);
 if (afterExecute(t, null))
 return true;
 return false;
}


从源码中可以看出,`addWorker(Runnable firstTask, boolean core)`方法首先会尝试创建新线程。如果线程集合中有可用的线程,则会从线程集合中取出一个线程来执行该任务。

### `workerStart(Runnable task)`

javaprivate void workerStart(Runnable task) {
 Thread t = currentThread();
 if (t.isAlive()) throw new Error("task != null, thread.holdsLock(this)");
 int c = ctl.get();
 if (!isRunning(c)) {
 Worker w;
 final ReentrantLock mainLock = this.mainLock;
 mainLock.lock();
 try {
 if (workerCountOf(c) ==0)
 t = getNewThread(false);
 else t = addWorkerWaiter(task, false);
 } finally {
 mainLock.unlock();
 }
 if (t == null)
 return;
 }
 Worker w = new Worker(this, task);
 Thread.startThread(w);
}


从源码中可以看出,`workerStart(Runnable task)`方法首先会尝试创建新线程。如果线程集合中有可用的线程,则会从线程集合中取出一个线程来执行该任务。

**五、总结**

本文深入探讨了ThreadPoolExecutor的底层原理和源码分析。通过对关键方法的源码分析,可以看出,ThreadPoolExecutor的工作流程主要包括任务提交、线程创建、任务执行和任务完成四个步骤。在这些步骤中,ThreadPoolExecutor会尝试将任务添加到线程集合中,如果线程集合中有可用的线程,则会从线程集合中取出一个线程来执行该任务。如果线程集合中没有可用的线程,则会创建新线程并添加到线程集合中。

相关标签:python开发语言
其他信息

其他资源

Top