在多线程编程中,线程池是一个关键的工具,可以有效地管理线程的生命周期,提高程序的性能和资源利用率。Java提供了一个强大的线程池实现,称为 ThreadPoolExecutor。
ExecutorService executor = new ThreadPoolExecutor(
corePoolSize, // 核心线程数
maximumPoolSize, // 最大线程数
keepAliveTime, // 线程空闲时间
timeUnit, // 时间单位
workQueue, // 工作队列
threadFactory, // 线程工厂
rejectionPolicy // 拒绝策略
);
LinkedBlockingQueue
(无界队列)或 ArrayBlockingQueue
(有界队列)等。LinkedBlockingQueue(链表阻塞队列):
LinkedBlockingQueue
是一个基于链表实现的无界队列,可以无限制地增加元素。BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>();
ArrayBlockingQueue(数组阻塞队列):
ArrayBlockingQueue
是一个基于数组实现的有界队列,必须指定队列的容量。BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(capacity);
SynchronousQueue(同步队列):
SynchronousQueue
是一个没有存储元素的队列,每个插入操作必须等待另一个线程的对应移除操作。BlockingQueue<Runnable> workQueue = new SynchronousQueue<>();
PriorityBlockingQueue(优先级队列):
PriorityBlockingQueue
是一个无界的优先级队列,可以根据元素的优先级顺序进行处理。Comparable
接口或者传入自定义的 Comparator
。BlockingQueue<Runnable> workQueue = new PriorityBlockingQueue<>();
DelayQueue(延迟队列):
DelayQueue
是一个无界的队列,用于存放实现了 Delayed
接口的元素。BlockingQueue<Runnable> workQueue = new DelayQueue<>();
LinkedTransferQueue(链表传输队列):
LinkedTransferQueue
是一个无界队列,可以在生产者和消费者之间传输元素。tryTransfer
方法尝试直接将元素传输给消费者,如果不成功则添加到队列中。BlockingQueue<Runnable> workQueue = new LinkedTransferQueue<>();
LinkedBlockingDeque(链表双向阻塞队列):
LinkedBlockingDeque
是一个基于链表实现的无界双向队列,可以在队头和队尾插入、移除元素。BlockingQueue<Runnable> workQueue = new LinkedBlockingDeque<>();
自定义工作队列:
BlockingQueue
接口。总的来说,选择工作队列的类型取决于你的具体需求和场景。不同的队列类型在不同的场景下有着不同的优劣势,需要根据实际情况来选择。
ThreadPoolExecutor.AbortPolicy
:直接抛出异常。ThreadPoolExecutor.CallerRunsPolicy
:由调用者所在的线程执行任务。ThreadPoolExecutor.DiscardPolicy
:直接丢弃任务。ThreadPoolExecutor.DiscardOldestPolicy
:丢弃最老的任务。import java.util.concurrent.*;
public class ThreadPoolExample {
public static void main(String[] args) {
int corePoolSize = 5;
int maximumPoolSize = 10;
long keepAliveTime = 60L;
TimeUnit timeUnit = TimeUnit.SECONDS;
BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>(100);
ThreadFactory threadFactory = Executors.defaultThreadFactory();
RejectedExecutionHandler rejectionPolicy = new ThreadPoolExecutor.CallerRunsPolicy();
ExecutorService executor = new ThreadPoolExecutor(
corePoolSize,
maximumPoolSize,
keepAliveTime,
timeUnit,
workQueue,
threadFactory,
rejectionPolicy
);
// 提交任务给线程池
for (int i = 0; i < 20; i++) {
executor.execute(new Task(i));
}
// 关闭线程池
executor.shutdown();
}
static class Task implements Runnable {
private final int taskId;
public Task(int taskId) {
this.taskId = taskId;
}
@Override
public void run() {
System.out.println("Task " + taskId + " is running.");
}
}
}
在这个示例中,我们创建了一个 ThreadPoolExecutor,配置了各种参数,然后提交了20个任务给线程池执行。
protected ExecutorService executorService= new ThreadPoolExecutor(
10,
15,
30,
TimeUnit.SECONDS,
new ArrayBlockingQueue<>(1024),
r -> {
Thread t = new Thread(r);
t.setName("SAVE_D_STORAGE");
t.setPriority(Thread.NORM_PRIORITY + 2); // 增加优先级
return t;
},
new ThreadPoolExecutor.CallerRunsPolicy());
ThreadPoolExecutor 适用于需要在后台执行异步任务的场景,比如:
ThreadPoolExecutor 是 Java 多线程编程中非常重要的工具,能够高效地管理线程的生命周期,提高程序性能和资源利用率。合理配置线程池参数,选择适当的拒绝策略,是保证系统稳定性和性能的关键。