zoukankan      html  css  js  c++  java
  • 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的方式。
  • 相关阅读:
    CS round--36
    Vijos 1002 过河 dp + 思维
    汇编模拟36选7
    1137
    E. Mike and Foam 容斥原理
    Even-odd Boxes hackerrank 分类讨论
    112. 作业之地理篇 最小费用最大流模板题
    1550: Simple String 最大流解法
    Sam's Numbers 矩阵快速幂优化dp
    java.sql.SQLSyntaxErrorException: ORA-01722: 无效数字
  • 原文地址:https://www.cnblogs.com/zhangmingda/p/14677842.html
Copyright © 2011-2022 走看看