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

简介: 通过Callable和Future结合线程池,实现有返回值的多线程编程。Callable定义带返回值的任务,submit提交后返回Future对象,调用get()可获取结果并处理异常。支持单任务与多任务并发,适用于数据并行计算等场景,提升执行效率。

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

一、核心原理

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

二、代码示例

1. 单任务场景:提交一个有返回值的任务

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. 多任务场景:提交多个有返回值的任务,批量获取结果

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的和为:45150

三、关键API说明

  1. executor.submit(Callable<T>)
    提交有返回值的任务,返回 Future<T> 对象。线程池会分配线程执行 call() 方法。

  2. Future<T>.get()

    • 阻塞当前线程,直到任务执行完毕并返回结果。
    • 若任务抛出异常,get() 会将异常封装为 ExecutionException 抛出。
    • 可使用 get(long timeout, TimeUnit unit) 设置超时时间,避免永久阻塞。
  3. Future<T>.isDone()
    判断任务是否执行完毕(返回 true 表示已完成,包括正常结束、异常终止、被取消)。

  4. Future<T>.cancel(boolean mayInterruptIfRunning)
    取消任务执行:

    • 若任务未开始,直接取消;
    • 若任务已开始,mayInterruptIfRunningtrue 则中断任务,否则允许任务完成。

四、优势总结

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

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

相关文章
|
14天前
|
文字识别 安全 程序员
PowerToys微软官方效率工具实操教程!Windows系统增强神器!
PowerToys是微软官方推出的免费开源工具集,集成20余款高效插件,如窗口管理、快速启动、批量重命名、OCR文字提取等,显著提升Windows使用体验,支持多屏协作、快捷操作,安全稳定,持续更新,适合各类用户优化工作效率。
146 6
|
2月前
|
网络安全 数据库 索引
Everything(文件搜索工具)安装教程!电脑端最强文件搜索神器
Everything是一款毫秒级响应的轻量级文件搜索工具,直接读取NTFS文件系统MFT,无需建库索引,安装包仅1.7MB,资源占用极低。输入关键词即可瞬间定位电脑中的文件与文件夹,支持快速筛选与浏览,大幅提升文件查找效率。
324 1
|
2月前
|
Java
Java基础知识总结(超详细整理)
本文系统总结Java基础知识,涵盖语法、面向对象(类与对象、封装、继承、多态)、常用类(String、包装类、集合框架)及异常处理等核心内容,结合代码示例深入浅出,助你扎实掌握Java编程基础。
154 1
|
2月前
|
Java
如何在Java中进行多线程编程
Java多线程编程常用方式包括:继承Thread类、实现Runnable接口、Callable接口(可返回结果)及使用线程池。推荐线程池以提升性能,避免频繁创建线程。结合同步与通信机制,可有效管理并发任务。
152 6
|
2月前
|
IDE Java 关系型数据库
如何利用Spring Initializr快速搭建项目
通过Spring Initializr可快速搭建Spring Boot项目。访问官网,配置项目信息,选择依赖(如Web、MyBatis、MySQL等),生成并下载项目压缩包,解压后导入IDE,自动构建完成,快速高效地初始化标准项目结构,提升开发效率。(238字)
369 3
|
2月前
|
存储 Oracle Java
java零基础学习者入门课程
本课程为Java零基础入门教程,涵盖环境搭建、变量、运算符、条件循环、数组及面向对象基础,每讲配示例代码与实践建议,助你循序渐进掌握核心知识,轻松迈入Java编程世界。
287 0
|
14天前
|
区块链 数据安全/隐私保护 计算机视觉
FSViewer看图软件安装教程!可以批量格式转换、批量重命名、批量压缩的看图软件(还有其他几款看图软件可以看看)
FSViewer是一款功能强大的免费看图软件,支持BMP、JPG、PNG、GIF、RAW等主流图片格式,具备快速浏览、批量格式转换、重命名、压缩及图片编辑功能,操作简便,适合日常图像处理需求。
199 72
|
3月前
|
数据安全/隐私保护 Windows
深度剖析:PDF 工具箱功能,编辑器操作及页面 / 图像提取技巧
PDF24 Tools是一款德国开发的免费PDF工具箱,18年始终免费,支持网页与Windows客户端。内置近50个工具,涵盖编辑、转换、合并、提取、加密等功能,操作简单,可离线使用,是高效处理PDF的理想选择。
573 0
|
8天前
|
安全 C++ Windows
使用教程!Geek UninstallerV1.5.3.170 深度卸载神器完全使用指南!彻底告别软件残留
Geek Uninstaller是一款免费、轻量级的深度卸载工具,能彻底清除软件残留文件和注册表项,解决系统卡慢、空间占用等问题。支持普通卸载、强制卸载及Windows预装应用清理,操作简单,无需安装,一键释放硬盘空间,提升系统性能。
232 8
|
22天前
|
Java 数据库 微服务
Java 学习路线可按「基础→进阶→实战→架构」四阶段推进
Java学习路线分四阶段:基础→进阶→实战→架构。涵盖语法、多线程、框架、微服务等核心内容,搭配项目实战与学习技巧,助你系统掌握Java开发技能,逐步成长为高级工程师。(238字)
161 4

热门文章

最新文章