线程池(ThreadPoolExecutor)的工作原理
线程池是一种用于管理和复用线程的机制,它可以减少线程创建和销毁的开销,提高程序的执行效率。ThreadPoolExecutor
是Java中实现线程池的一个类,它位于java.util.concurrent
包中。
线程池的工作原理如下:
- 任务提交:当有任务需要执行时,任务会被提交到线程池的任务队列中。
- 任务调度:线程池中的工作线程会从任务队列中取出任务并执行。
- 线程复用:执行完任务的工作线程不会被销毁,而是返回到线程池中等待下一个任务的提交。
- 动态调整:线程池可以根据任务的数量和系统的负载情况动态调整工作线程的数量。
自定义线程池
可以通过ThreadPoolExecutor
类的构造方法来创建自定义线程池。构造方法的参数如下:
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue)
corePoolSize
:核心线程数,即线程池中始终保持的线程数量。maximumPoolSize
:最大线程数,即线程池中允许的最大线程数量。keepAliveTime
:非核心线程的空闲存活时间,超过这个时间的非核心线程会被销毁。unit
:keepAliveTime
的时间单位。workQueue
:用于保存等待执行的任务的阻塞队列。
示例代码
以下是一个自定义线程池的示例:
import java.util.concurrent.*;
public class Main {
public static void main(String[] args) {
// 创建一个自定义线程池
ThreadPoolExecutor executor = new ThreadPoolExecutor(
5, // 核心线程数
10, // 最大线程数
60L, // 非核心线程的空闲存活时间
TimeUnit.SECONDS, // 时间单位
new LinkedBlockingQueue<>(100) // 任务队列
);
// 提交任务到线程池
for (int i = 0; i < 20; i++) {
executor.submit(() -> {
System.out.println(" 执行任务:" + Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
// 关闭线程池
executor.shutdown();
}
}
在这个示例中,我们创建了一个核心线程数为5,最大线程数为10的线程池。任务队列使用LinkedBlockingQueue
,容量为100。当提交的任务数量超过核心线程数时,线程池会创建新的非核心线程来处理任务,直到达到最大线程数。超过最大线程数的任务会被放入任务队列中等待执行。