
通过线程池实现有返回值的多线程编程,核心是使用 Callable 接口(定义有返回值的任务)和 Future 接口(获取任务结果)。以下是具体代码示例,包含单任务、多任务场景,并说明关键API的使用。
Callable<T>:泛型接口,其中 call() 方法是线程执行体,返回值类型为 T,可抛出异常。Future<T>:用于获取 Callable 任务的返回结果,通过 get() 方法阻塞等待结果(或超时获取)。ExecutorService 的 submit(Callable<T>) 方法提交任务,返回 Future<T> 对象。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 ThreadPoolSingleCallable {
public static void main(String[] args) {
// 1. 创建线程池(这里用固定大小为1的线程池)
ExecutorService executor = Executors.newFixedThreadPool(1);
// 2. 定义有返回值的任务(实现Callable接口,泛型为返回值类型)
Callable<Integer> task = new Callable<Integer>() {
@Override
public Integer call() throws Exception {
System.out.println("任务开始执行:计算1~100的和");
int sum = 0;
for (int i = 1; i <= 100; i++) {
sum += i;
}
Thread.sleep(1000); // 模拟任务耗时
System.out.println("任务执行完毕");
return sum; // 返回计算结果
}
};
// 3. 提交任务到线程池,获取Future对象(用于后续获取结果)
Future<Integer> future = executor.submit(task);
// 4. 关闭线程池(不再接受新任务,等待现有任务完成)
executor.shutdown();
// 5. 通过Future获取任务结果(get()会阻塞当前线程,直到任务完成)
try {
// 可选:设置超时时间,避免无限等待(如5秒超时)
// Integer result = future.get(5, TimeUnit.SECONDS);
Integer result = future.get();
System.out.println("1~100的和为:" + result); // 输出:5050
} catch (InterruptedException e) {
// 线程被中断时触发
System.out.println("任务被中断");
e.printStackTrace();
} catch (ExecutionException e) {
// 任务执行中抛出异常时触发
System.out.println("任务执行出错");
e.printStackTrace();
}
}
}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 ThreadPoolMultiCallable {
public static void main(String[] args) {
// 1. 创建线程池(核心线程数为3,适合并发执行多个任务)
ExecutorService executor = Executors.newFixedThreadPool(3);
// 2. 定义多个有返回值的任务(计算1~n的和,n分别为100、200、300)
List<Callable<Integer>> tasks = new ArrayList<>();
tasks.add(new SumTask(100)); // 任务1:1~100的和
tasks.add(new SumTask(200)); // 任务2:1~200的和
tasks.add(new SumTask(300)); // 任务3:1~300的和
// 3. 批量提交任务,获取所有Future对象(存储结果的"占位符")
List<Future<Integer>> futures = new ArrayList<>();
for (Callable<Integer> task : tasks) {
Future<Integer> future = executor.submit(task);
futures.add(future);
}
// 4. 关闭线程池
executor.shutdown();
// 5. 遍历Future集合,获取所有任务的结果
for (int i = 0; i < futures.size(); i++) {
Future<Integer> future = futures.get(i);
try {
int result = future.get(); // 阻塞等待当前任务结果
System.out.println("1~" + (i + 1) * 100 + "的和为:" + result);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
// 自定义Callable任务:计算1~max的和
static class SumTask implements Callable<Integer> {
private int max;
public SumTask(int max) {
this.max = max;
}
@Override
public Integer call() throws Exception {
int sum = 0;
for (int i = 1; i <= max; i++) {
sum += i;
}
System.out.println(Thread.currentThread().getName() + " 完成计算(1~" + max + ")");
return sum;
}
}
}输出结果(线程名可能不同,体现并发执行):
pool-1-thread-1 完成计算(1~100)
pool-1-thread-2 完成计算(1~200)
pool-1-thread-3 完成计算(1~300)
1~100的和为:5050
1~200的和为:20100
1~300的和为:45150executor.submit(Callable<T>):undefined提交有返回值的任务,返回 Future<T> 对象。线程池会分配线程执行 call() 方法。Future<T>.get(): get() 会将异常封装为 ExecutionException 抛出。 get(long timeout, TimeUnit unit) 设置超时时间,避免永久阻塞。Future<T>.isDone():undefined判断任务是否执行完毕(返回 true 表示已完成,包括正常结束、异常终止、被取消)。Future<T>.cancel(boolean mayInterruptIfRunning):undefined取消任务执行: mayInterruptIfRunning 为 true 则中断任务,否则允许任务完成。List<Future> 批量管理多个任务的结果。 Future 提供阻塞获取、超时控制等功能,灵活处理异步结果。 这种方式适合需要多线程并发计算并汇总结果的场景(如数据分片计算、并行查询等)。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。