首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >代码示例说明如何通过线程池实现有返回值的多线程编程

代码示例说明如何通过线程池实现有返回值的多线程编程

原创
作者头像
啦啦啦191
发布2025-11-12 15:21:30
发布2025-11-12 15:21:30
1380
举报
文章被收录于专栏:Java开发Java开发

通过线程池实现有返回值的多线程编程,核心是使用 Callable 接口(定义有返回值的任务)和 Future 接口(获取任务结果)。以下是具体代码示例,包含单任务、多任务场景,并说明关键API的使用。

一、核心原理

  1. Callable<T>:泛型接口,其中 call() 方法是线程执行体,返回值类型为 T,可抛出异常。
  2. Future<T>:用于获取 Callable 任务的返回结果,通过 get() 方法阻塞等待结果(或超时获取)。
  3. 线程池:通过 ExecutorServicesubmit(Callable<T>) 方法提交任务,返回 Future<T> 对象。

二、代码示例

1. 单任务场景:提交一个有返回值的任务
代码语言:java
复制
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();
        }
    }
}
2. 多任务场景:提交多个有返回值的任务,批量获取结果
代码语言:java
复制
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;
        }
    }
}

输出结果(线程名可能不同,体现并发执行):

代码语言:txt
复制
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的和为:45150

三、关键API说明

  1. executor.submit(Callable<T>):undefined提交有返回值的任务,返回 Future<T> 对象。线程池会分配线程执行 call() 方法。
  2. Future<T>.get()
    • 阻塞当前线程,直到任务执行完毕并返回结果。
    • 若任务抛出异常,get() 会将异常封装为 ExecutionException 抛出。
    • 可使用 get(long timeout, TimeUnit unit) 设置超时时间,避免永久阻塞。
  3. Future<T>.isDone():undefined判断任务是否执行完毕(返回 true 表示已完成,包括正常结束、异常终止、被取消)。
  4. Future<T>.cancel(boolean mayInterruptIfRunning):undefined取消任务执行:
    • 若任务未开始,直接取消;
    • 若任务已开始,mayInterruptIfRunningtrue 则中断任务,否则允许任务完成。

四、优势总结

  1. 高效管理线程:线程池复用线程,减少创建/销毁开销。
  2. 批量处理任务:通过 List<Future> 批量管理多个任务的结果。
  3. 可控的结果获取Future 提供阻塞获取、超时控制等功能,灵活处理异步结果。

这种方式适合需要多线程并发计算并汇总结果的场景(如数据分片计算、并行查询等)。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、核心原理
  • 二、代码示例
    • 1. 单任务场景:提交一个有返回值的任务
    • 2. 多任务场景:提交多个有返回值的任务,批量获取结果
  • 三、关键API说明
  • 四、优势总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档