
在Java中,线程池是管理多线程的高效方式,它通过复用线程减少频繁创建/销毁线程的开销。以下通过代码示例详细说明如何使用线程池实现多线程编程,包括线程池的创建、提交任务、获取结果及关闭线程池等核心操作。
Java通过java.util.concurrent包提供线程池支持,核心类和接口:
ExecutorService:线程池核心接口,定义了提交任务、关闭线程池等方法。Executors:工具类,提供快速创建常见线程池的静态方法(实际开发中推荐ThreadPoolExecutor自定义线程池,更灵活)。ThreadPoolExecutor:线程池的核心实现类,可自定义核心线程数、最大线程数等参数。Runnable任务(无返回值)import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadPoolRunnableDemo {
public static void main(String[] args) {
// 1. 创建线程池(这里用Executors.newFixedThreadPool创建固定大小的线程池)
// 核心线程数为3,即同时最多运行3个线程
ExecutorService executor = Executors.newFixedThreadPool(3);
// 2. 提交任务(Runnable接口,无返回值)
for (int i = 0; i < 5; i++) { // 提交5个任务
final int taskId = i; // 任务编号
// 提交Runnable任务
executor.submit(new Runnable() {
@Override
public void run() {
// 任务逻辑:打印线程名和任务ID,模拟耗时操作
System.out.println("线程" + Thread.currentThread().getName()
+ " 执行任务" + taskId);
try {
Thread.sleep(1000); // 模拟任务耗时1秒
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
// 3. 关闭线程池(重要!否则程序会一直运行)
// shutdown():不再接受新任务,等待已有任务执行完毕后关闭
executor.shutdown();
}
}输出说明:
线程池有3个核心线程,5个任务会分两批执行(前3个同时执行,1秒后执行剩余2个),输出类似:
线程pool-1-thread-1 执行任务0
线程pool-1-thread-2 执行任务1
线程pool-1-thread-3 执行任务2
(1秒后)
线程pool-1-thread-1 执行任务3
线程pool-1-thread-2 执行任务4Callable任务(有返回值)如果需要线程返回结果,可提交Callable任务,通过Future获取结果。
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class ThreadPoolCallableDemo {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 1. 创建线程池(单线程池,仅1个线程)
ExecutorService executor = Executors.newSingleThreadExecutor();
// 2. 提交Callable任务(有返回值,这里返回1~n的和)
Callable<Integer> task = new Callable<Integer>() {
@Override
public Integer call() throws Exception {
int sum = 0;
for (int i = 1; i <= 100; i++) {
sum += i;
}
return sum; // 返回计算结果
}
};
// 提交任务并获取Future对象(用于获取结果)
Future<Integer> future = executor.submit(task);
// 3. 关闭线程池
executor.shutdown();
// 4. 通过Future获取结果(get()会阻塞,直到任务完成)
int result = future.get();
System.out.println("1~100的和:" + result); // 输出:5050
}
}多任务批量获取结果示例:
public class ThreadPoolMultiCallableDemo {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 创建固定大小为2的线程池
ExecutorService executor = Executors.newFixedThreadPool(2);
// 存储多个Future对象
List<Future<Integer>> futures = new ArrayList<>();
// 提交3个任务(计算1~n的和)
for (int i = 1; i <= 3; i++) {
final int num = i * 100; // 分别计算1~100、1~200、1~300的和
Future<Integer> future = executor.submit(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
int sum = 0;
for (int j = 1; j <= num; j++) {
sum += j;
}
return sum;
}
});
futures.add(future);
}
// 关闭线程池
executor.shutdown();
// 遍历Future获取所有结果
for (int i = 0; i < futures.size(); i++) {
System.out.println("1~" + (i + 1) * 100 + "的和:" + futures.get(i).get());
}
}
}输出:
1~100的和:5050
1~200的和:20100
1~300的和:45150ThreadPoolExecutor)Executors创建的线程池有潜在风险(如newCachedThreadPool可能创建大量线程导致OOM),实际开发中推荐用ThreadPoolExecutor自定义参数:
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class CustomThreadPoolDemo {
public static void main(String[] args) {
// 自定义线程池参数
int corePoolSize = 2; // 核心线程数(常驻线程)
int maximumPoolSize = 4; // 最大线程数(核心线程+临时线程)
long keepAliveTime = 60; // 临时线程空闲时间
TimeUnit unit = TimeUnit.SECONDS; // 时间单位
// 任务队列(容量为2,超出的任务会创建临时线程)
ArrayBlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(2);
// 创建自定义线程池
ThreadPoolExecutor executor = new ThreadPoolExecutor(
corePoolSize,
maximumPoolSize,
keepAliveTime,
unit,
workQueue
);
// 提交5个任务
for (int i = 0; i < 5; i++) {
final int taskId = i;
executor.submit(new Runnable() {
@Override
public void run() {
System.out.println("线程" + Thread.currentThread().getName()
+ " 执行任务" + taskId);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
// 关闭线程池
executor.shutdown();
}
}参数说明:
方法 | 说明 |
|---|---|
| 提交无返回值的任务,返回 |
| 提交有返回值的任务,返回 |
| 平缓关闭:不再接受新任务,等待现有任务完成后关闭 |
| 强制关闭:尝试中断所有任务,返回未执行的任务 |
| 判断线程池是否已关闭 |
| 判断所有任务是否执行完毕 |
通过线程池实现多线程编程是工业级开发的最佳实践,需根据业务场景合理选择线程池类型和参数。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。