java 多线程:Callable接口;FutureTask类实现对象【Thread、Runnable、Callable三种方式实现多线程的区别】

Callable接口介绍:

Java5开始,Java提供了Callable接口,像是Runnable接口的增强版,Callable接口提供了一个 call()方法可以作为线执行体.
call()方法比run()方法功更强大。call()方法可以有返回值,call()方法可以抛出异常

 实现方法:

  1. 创建Callable接口实现类对象
  2. 创建FutureTask类实现对象
  3. 创建Thread类实现对象
  4. 调用Thread类实现对象start()方法提交线程任务
 
示例:
复制代码
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

/**
 * @ClassName CallableExample
 * @projectName: object1
 * @author: Zhangmingda
 * @description: XXX
 * date: 2021/4/19.
 */
public class CallableExample {
    public static void main(String[] args) {
        /**
         * 实现Callable接口必须重写call方法。
         */
        Callable<Integer> callable = new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                return null;
            }
        };
        /**
         * 该接口又是函数式接口只有一个call方法,可以用lambda表达式替代如下
         */
        Callable<Integer> callable1 = () -> null;

        /**
         * 测试多线程实际应用:计算1+2+3+...+100的和
         * 接口实现类对象callable2
         */
        Callable<Integer> callable2 = () -> {
            int num = 0;
            for(int i=1; i<=100; i++){
                num +=i;
            }
            System.out.println("I am "+ Thread.currentThread().getName() + "  My result:" + num);
            return num;
        };
        //使用Set集合存储计划任务FutureTask类对象,便于获取结果
        Set<FutureTask> futureTasks = new HashSet<>();
        //跑10个线程
        for(int i=0; i<10; i++){
            //通过callable接口实现类 创建计划任务FutureTask实现类对象
            FutureTask<Integer> futureTask = new FutureTask<>(callable2);
            //向集合中添加计划任务类对象
            futureTasks.add(futureTask);
            //通过FutureTask实现类创建线程实体类Thread类对象,并提交给jvm运行
            new Thread(futureTask).start();
        }

        //获取每个任务的结果计算总和
        int resultCount =0;
        for(FutureTask<Integer> futureTask :futureTasks){
            try {
                //计算所有任务结果总和
                resultCount += futureTask.get();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
        System.out.println("10个任务计算总和:" + resultCount);
    }
}
复制代码

 Thread、Runnable、Callable三种方式实现多线程的优势区别

  1. 继承:采用Thread方式实现的线程不能继承其他父类,采用Runnable和Callable接口的可以继承其他父类,但是编程上采用Thread的方式可以直接使用getName()方法,而采用Runnable和Callable接口的方式需要先获取Thread.currentThread();
  2. 共享:采用Runnable和Callable的方式,可以多个线程公用一个Target对象,而采用Thread的方式不能,所以非常适合多个相同线程来处理同一份资源的情况
  3. 返回值:如果需要线程有返回值的需要使用Callable的方式。

 

posted on   zhangmingda  阅读(121)  评论(0编辑  收藏  举报

编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
历史上的今天:
2020-04-19 HTML标签一览
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

导航

统计

点击右上角即可分享
微信分享提示