zoukankan      html  css  js  c++  java
  • Future和Callable

    除了线程池可以治理线程外,Future和Callable也可以治理线程。

    Runnable缺陷

      Runnable的run无返回值

      不能抛出Checked Exception

      我们通过下面实例去演示。

      

       我们思考下为什么没有返回值呢?一般调用Runnable的类为Thread,Thread是JDK提供,我们无法做处理。

      Callable接口提供了返回值。

    Callable接口

      Callable接口是可以有返回值和异常的,如下源码所示:

      

    Feature类

      Future可搭配Callable来使用。Feature是一个存储器

    Future与Callable关系

      我们可以通过Future的get方法来获取Callable接口执行的返回值;

      我们可以通过Feature的isDone方法来判断Callable是否已经执行结束了,也可以取消这个任务。

      call未执行完之前,用Feature的get时会阻塞,直到有返回结果

    Future主要方法

      主要方法如下:

      1.get 任务执行完成了,则直接返回;任务未完成,get方法会进行阻塞直到任务完成;任务执行过程中抛出了异常时,get方法也会抛出异常,get只抛出ExecutionException;

        任务取消时,get抛出CancellationException异常;任务超时时,抛出TimeoutException

      2.get(long timeout,TimeUnit unit) 有超时的获取,参照上方法

      3.cancel 取消任务执行;取消策略需要关注

      4.isDone 判断线程是否执行完毕,执行完毕不代表成功执行。

      5.isCancelled 是否取消

      

     Future基本用法实例

           我们给线程池提供一个任务,获取对应Future,见如下代码所示:

      

    package com.yang.callable;
    
    import java.util.Random;
    import java.util.concurrent.*;
    
    public class OneFutureDemo {
        public static void main(String[] args) {
            ExecutorService executorService= Executors.newFixedThreadPool(10);
            Future<Integer> future = executorService.submit(new CallableTask<Integer>());
            try {
                System.out.println(future.get());
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
            executorService.shutdown();
        }
        
        static class CallableTask<I extends Number> implements Callable<Integer>{
            @Override
            public Integer call() throws Exception {
                Thread.sleep(1000);
                return new Random().nextInt();
            }
        }
        
    }
    

      运行结果如下所示:

      

    FutureLamda实例

      我们使用Lamda来实现,请看下代码:

      

    package com.yang.callable;
    
    import java.util.Random;
    import java.util.concurrent.*;
    
    public class FutureLamdaDemo {
        public static void main(String[] args) {
            ExecutorService executorService= Executors.newFixedThreadPool(10);
            Callable<Integer> callable=()->{
              Thread.sleep(3000);
              return new Random().nextInt();
            };
            Future<Integer> future = executorService.submit(callable);
            try {
                System.out.println(future.get());
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
            executorService.shutdown();
        }
        
    
        
    }
    

      

    Future批量接收实例代码

      Future批量接收Callable,实例代码如下所示:

      

    package com.yang.callable;
    
    import java.util.ArrayList;
    import java.util.Random;
    import java.util.concurrent.*;
    
    public class MultiFutureDemo {
        public static void main(String[] args) {
            ExecutorService executorService = Executors.newFixedThreadPool(2);
            ArrayList<Future<Integer>> futureArrayList = new ArrayList<Future<Integer>>();
            for (int i = 0; i < 10; i++) {
                futureArrayList.add(executorService.submit(new CallableTask()));
            }
    
            for (int i = 0; i < 10; i++) {
                try {
                    Integer integer = futureArrayList.get(i).get();
                    System.out.println(integer);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (ExecutionException e) {
                    e.printStackTrace();
                }
            }
        }
        static class CallableTask implements Callable<Integer>{
            @Override
            public Integer call() throws Exception {
                Thread.sleep(3000);
                return new Random().nextInt();
            }
        }
    }
    

      运行结果如下所示:

      

     Future在执行过程中抛出了异常实例

      本实例演示get方法抛出了异常,实例代码如下所示:

      

    package com.yang.callable;
    
    import java.util.concurrent.*;
    
    public class GetExecption {
        public static void main(String[] args) {
            ExecutorService executorService = Executors.newFixedThreadPool(2);
            Future<Integer> future=executorService.submit(new CallableTask());
            try{
                future.get();
            }catch (IllegalArgumentException e){
                System.out.println("线程内部抛出异常");
            }catch (ExecutionException e){
                System.out.println("执行过程中抛出异常");
            } catch (InterruptedException e) {
                e.printStackTrace();
                System.out.println("中断异常");
            }
        }
        static class CallableTask implements Callable<Integer>{
            @Override
            public Integer call() throws Exception {
                throw new IllegalArgumentException("不合法的参数异常");
            }
        }
    }
    

      执行结果如下:

      

    Future的isDone实例

      isDone演示如下所示:

      

    package com.yang.callable;
    
    import java.util.concurrent.*;
    
    public class GetExecption {
        public static void main(String[] args) {
            ExecutorService executorService = Executors.newFixedThreadPool(2);
            Future<Integer> future=executorService.submit(new CallableTask());
            try{
                future.get();
            }catch (IllegalArgumentException e){
                System.out.println("线程内部抛出异常");
            }catch (ExecutionException e){
                System.out.println("执行过程中抛出异常");
            } catch (InterruptedException e) {
                e.printStackTrace();
                System.out.println("中断异常");
            }
            System.out.println(future.isDone());
    
        }
        static class CallableTask implements Callable<Integer>{
            @Override
            public Integer call() throws Exception {
                throw new IllegalArgumentException("不合法的参数异常");
            }
        }
    }
    

      运行结果

      

     Future获取任务超时实例

      本实例演示get的超时方法,当超时后,我们取消这个任务。我们同事演示下cancel方法传入true或者false

      

    package com.yang.callable;
    
    import java.util.Calendar;
    import java.util.concurrent.*;
    
    /**
     * 本实例演示Future超时
     */
    public class TimeoutFutureDemo {
        private static String defaultAdStr = "我是默认的";
    
        public static void main(String[] args) {
            ExecutorService executorService = Executors.newFixedThreadPool(2);
            Future<String> future = executorService.submit(new FutureTask());
            try {
                String s = future.get(2000, TimeUnit.MILLISECONDS);
            } catch (InterruptedException e) {
                System.out.println("中断了");
            } catch (ExecutionException e) {
                System.out.println("执行异常");
            } catch (TimeoutException e) {
                System.out.println("超时了");
                //控制是否要中断,true:允许中断
                boolean cancelStatus = future.cancel(true);
                System.out.println(cancelStatus);
            }
        }
    
    
        static class FutureTask implements Callable<String> {
            @Override
            public String call() throws Exception {
    
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    System.out.println("中断了,返回默认的");
                    return defaultAdStr;
                }
                return "外部获取的消息";
            }
        }
    }
    

      运行结果如下所示:

      

       Cancel方法的总结

      1.cancel方法支持传入true和false

      2.当传入true时,需要考虑当前线程是否支持中断,中断后的业务逻辑是否正确

      3.任务都已经开始,我们是否需要其执行完毕,需要则用false

         

      

      

      

  • 相关阅读:
    go开发 modules 的使用和代理
    利用 nodejs 解析 m3u8 格式文件,并下 ts 合并为 mp4
    别再@官方啦,普天同庆加国旗
    vue基于 element ui 的按钮点击节流
    react-router 5.0 的鉴权
    slot 组件的内部传值 v-slot 的使用
    javascript 写一个ajax 自动拦截,并下载数据
    Linux 命令大全
    http 基础
    MongoDB Shell (mongo)
  • 原文地址:https://www.cnblogs.com/cnxieyang/p/12779349.html
Copyright © 2011-2022 走看看