Java 并发编程中,java.util.concurrent
(简称 JUC)包提供了多种线程池实现,包括 Executor
, Callable
, FutureTask
, 和 ThreadPoolExecutor
。这些工具特别设计用于多线程环境,可以提高并发程序的性能和安全性。下面将详细介绍这些线程池工具的特点及其使用方式。
Executor
Executor
是一个接口,它定义了一个基本的方法 execute(Runnable command)
,用于提交任务到线程池中执行。Executor
本身并不实现具体的线程池逻辑,而是提供了一个高层的抽象,方便使用。
示例代码:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ExecutorExample {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(3); // 创建一个固定大小的线程池
// 提交任务
for (int i = 0; i < 5; i++) {
executor.execute(() -> {
System.out.println(Thread.currentThread().getName() + " is working");
try {
Thread.sleep(1000); // 模拟工作
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
}
executor.shutdown(); // 关闭线程池
while (!executor.isTerminated()) {
// 等待所有任务完成
}
System.out.println("Finished all tasks.");
}
}
Callable 和 FutureTask
Callable
是一个接口,与 Runnable
类似,但它可以返回结果,并且可以抛出异常。FutureTask
是一个实现了 Runnable
和 Future
接口的类,它可以将 Callable
包装起来,并且可以获取计算的结果。
示例代码:
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
public class CallableExample {
public static void main(String[] args) {
Callable<Integer> callable = () -> {
System.out.println(Thread.currentThread().getName() + " is working");
try {
Thread.sleep(1000); // 模拟工作
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
return 100; // 返回结果
};
FutureTask<Integer> futureTask = new FutureTask<>(callable);
new Thread(futureTask).start(); // 启动线程执行任务
try {
int result = futureTask.get(); // 获取结果
System.out.println("Result: " + result);
} catch (Exception e) {
e.printStackTrace();
}
}
}
ThreadPoolExecutor
ThreadPoolExecutor
是一个具体的线程池实现,它提供了更多的配置选项,可以更细粒度地控制线程池的行为。
特点:
- 可以设置核心线程数、最大线程数、空闲线程存活时间、任务队列等参数。
- 支持多种拒绝策略,如丢弃任务、终止线程等。
- 提供了详细的监控信息,如线程池状态、活跃线程数等。
示例代码:
import java.util.concurrent.*;
public class ThreadPoolExecutorExample {
public static void main(String[] args) {
ThreadPoolExecutor executor = new ThreadPoolExecutor(
3, // 核心线程数
5, // 最大线程数
60, // 空闲线程存活时间(秒)
TimeUnit.SECONDS,
new ArrayBlockingQueue<>(10), // 任务队列
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy()); // 拒绝策略
// 提交任务
for (int i = 0; i < 15; i++) {
executor.execute(() -> {
System.out.println(Thread.currentThread().getName() + " is working");
try {
Thread.sleep(1000); // 模拟工作
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
}
executor.shutdown(); // 关闭线程池
while (!executor.isTerminated()) {
// 等待所有任务完成
}
System.out.println("Finished all tasks.");
}
}
总结
Executor
, Callable
, FutureTask
, 和 ThreadPoolExecutor
都是 Java 并发编程中常用的线程池工具,它们各自解决了不同的问题。
- Executor 提供了一个高层的抽象来提交任务到线程池中执行。
- Callable 和 FutureTask 用于创建可以返回结果的任务,并且可以获取计算的结果。
- ThreadPoolExecutor 提供了更详细的配置选项,可以更细粒度地控制线程池的行为。
在使用这些线程池工具时,通常会结合具体的并发需求来选择合适的工具。这些工具可以有效地帮助管理线程的生命周期,提高并发性能。