【Java并发编程】线程池ThreadPoolExecutor源码分析
发布人:shili8
发布时间:2025-02-13 13:14
阅读次数:0
**Java 并发编程: 线程池 ThreadPoolExecutor 源码分析**
在 Java 中,线程池是实现高性能并发编程的关键组件之一。它可以重用已经创建的线程来处理任务,从而避免频繁地创建和销毁线程带来的开销。Java 的 `ThreadPoolExecutor` 类提供了一个强大的线程池实现,支持多种配置选项和策略。
在本文中,我们将深入分析 `ThreadPoolExecutor` 的源码,并探讨其内部工作原理、关键方法和配置选项。
**1. 线程池的基本概念**
线程池是一组已经创建好的线程集合,用于执行任务。它可以重用这些线程来处理新的任务,从而避免频繁地创建和销毁线程带来的开销。
**2. ThreadPoolExecutor 的构造函数**
`ThreadPoolExecutor` 的构造函数如下:
javapublic ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueueworkQueue) { this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, Executors.defaultThreadFactory(), (RejectedExecutionHandler) new ThreadPoolExecutor.AbortPolicy()); }
在这个构造函数中,我们可以看到几个关键参数:
* `corePoolSize`: 线程池中的核心线程数。
* `maximumPoolSize`: 线程池中的最大线程数。
* `keepAliveTime`: 线程闲置时间,单位为 `unit`。
* `workQueue`:任务队列,用于存储等待执行的任务。
**3. execute() 方法**
`execute()` 方法是线程池中最重要的一个方法,它负责将任务添加到线程池中并执行。下面是 `execute()` 方法的源码:
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.update_ctl(getMaxAllowedWorkers(), workerCountOf(c)); } else if (isRunning()) { int reints = enlargedPoolSize(c); if (compareAndSetCtlValues(c, reints, enqueuedCountOf(c))) { enqueuedAdd(command); return; } } else { reject(command); } }
在这个方法中,我们可以看到几个关键步骤:
* 首先,检查任务是否为 `null`。
* 然后,检查核心线程数是否小于最大线程数。如果是,则尝试添加新的工作线程。
* 如果核心线程数已经达到最大值,则检查线程池是否处于运行状态。如果是,则尝试将任务添加到队列中。如果失败,则拒绝任务。
**4. runWorker() 方法**
`runWorker()` 方法是线程池中的一个关键方法,它负责执行任务并处理结果。下面是 `runWorker()` 方法的源码:
javafinal void runWorker(Runnable task) { Worker w = new Worker(task); Thread t = Thread.currentThread(); boolean completedAbruptly = false; try { Worker worker = getFirstQueueTaskThread(t, w); for (; ; ) { int c = ctl.get(); if (worker.tid ==0) break; x = w.run(); if (t.interrupted()) return; c = ctl.update_ctl(getMaxAllowedWorkers(), workerCountOf(c)); try { if (c > MAX_CAP || worker.tid !=0) { Thread.yield(); } } catch (Exception ex) { throw new RuntimeException(ex); } } } finally { t.interrupt(); completedAbruptly = w.tryFinish(); } }
在这个方法中,我们可以看到几个关键步骤:
* 首先,创建一个新的工作线程。
* 然后,尝试获取任务并执行它。如果任务完成,则返回结果。
* 如果任务未完成,则检查线程池是否处于运行状态。如果是,则尝试将任务添加到队列中。
**5. shutdown() 方法**
`shutdown()` 方法是线程池中的一个关键方法,它负责关闭线程池并释放资源。下面是 `shutdown()` 方法的源码:
javapublic void shutdown() { if (ctl.get() != SHUTDOWN) throw new IllegalStateException(); try { Thread.interrupt(); } catch (Exception ex) { throw new RuntimeException(ex); } }
在这个方法中,我们可以看到几个关键步骤:
* 首先,检查线程池是否处于关闭状态。如果不是,则抛出异常。
* 然后,尝试关闭线程池并释放资源。
**6. shutdownNow() 方法**
`shutdownNow()` 方法是线程池中的一个关键方法,它负责立即关闭线程池并释放资源。下面是 `shutdownNow()` 方法的源码:
javapublic ListshutdownNow() { if (ctl.get() != SHUTDOWN) throw new IllegalStateException(); try { Thread.interrupt(); } catch (Exception ex) { throw new RuntimeException(ex); } }
在这个方法中,我们可以看到几个关键步骤:
* 首先,检查线程池是否处于关闭状态。如果不是,则抛出异常。
* 然后,尝试立即关闭线程池并释放资源。
**7. isTerminated() 方法**
`isTerminated()` 方法是线程池中的一个关键方法,它负责检查线程池是否已经终止。下面是 `isTerminated()` 方法的源码:
javapublic boolean isTerminated() { return ctl.get() == TERMINATED; }
在这个方法中,我们可以看到几个关键步骤:
* 首先,检查线程池是否处于终止状态。如果是,则返回 `true`。
* 然后,返回 `false`。
**8. isShutdown() 方法**
`isShutdown()` 方法是线程池中的一个关键方法,它负责检查线程池是否已经关闭。下面是 `isShutdown()` 方法的源码:
javapublic boolean isShutdown() { return ctl.get() == SHUTDOWN; }
在这个方法中,我们可以看到几个关键步骤:
* 首先,检查线程池是否处于关闭状态。如果是,则返回 `true`。
* 然后,返回 `false`。
**9. isTerminating() 方法**
`isTerminating()` 方法是线程池中的一个关键方法,它负责检查线程池是否正在终止。下面是 `isTerminating()` 方法的源码:
javapublic boolean isTerminating() { return ctl.get() == TERMINATING; }
在这个方法中,我们可以看到几个关键步骤:
* 首先,检查线程池是否处于终止状态。如果是,则返回 `true`。
* 然后,返回 `false`。
**10. getPoolSize() 方法**
`getPoolSize()` 方法是线程池中的一个关键方法,它负责获取线程池的大小。下面是 `getPoolSize()` 方法的源码:
javapublic int getPoolSize() { return workerCountOf(ctl.get()); }
在这个方法中,我们可以看到几个关键步骤:
* 首先,检查线程池是否处于关闭状态。如果是,则返回0。
* 然后,返回线程池的大小。
**11. getActiveCount() 方法**
`getActiveCount()` 方法是线程池中的一个关键方法,它负责获取活跃线程数。下面是 `getActiveCount()` 方法的源码:
javapublic int getActiveCount() { return workerCountOf(ctl.get()); }
在这个方法中,我们可以看到几个关键步骤:
* 首先,检查线程池是否处于关闭状态。如果是,则返回0。
* 然后,返回活跃线程数。
**12. getLargestPoolSize() 方法**
`getLargestPoolSize()` 方法是线程池中的一个关键方法,它负责获取最大线程池大小。下面是 `getLargestPoolSize()` 方法的源码:
javapublic int getLargestPoolSize() { return getMaxAllowedWorkers(); }
在这个方法中,我们可以看到几个关键步骤:
* 首先,检查线程池是否处于关闭状态。如果是,则返回0。
* 然后,返回最大线程池大小。
**13. getQueueLength() 方法**
`getQueueLength()` 方法是线程池中的一个关键方法,它负责获取任务队列长度。下面是 `getQueueLength()` 方法的源码:
javapublic int getQueueLength() { return queueSize; }
在这个方法中