zoukankan      html  css  js  c++  java
  • Callable的Future模式

      线程实现方式:
                    1.继承Thread类
                    2.实现Runnable接口
                    3.线程池
                    4.Callable

      无论使用继承Thread类还是实现Runnable接口,还是使用线程池都没有办法解决2个问题
                    1.线程执行没有返回值结果
                    2.线程执行没有办法抛出异常,只能自己通过try-catch解决

      Callable和Runnable类似,在JUC包下,主要区别在于Callable中的call方法可以带返回值并且可以抛出异常
           如果需要执行Callable,需要Future实现类的支持,能够接受返回值结果,FutureTask是Future实现类

      调用Callable的第一种实现方案:

                    public class MyCallable implements Callable<String> {
                        @Override
                        public String call() throws Exception {
                            System.out.println("Callable接口中重写的Call方法,可以有返回值并且抛出异常");
                            return "callable";
                        }
    
                        public static void main(String[] args) throws ExecutionException, InterruptedException {
                            MyCallable myCallable=new MyCallable();
                            //利用FutureTask执行Callable并且接受结果
                            FutureTask<String> stringFutureTask = new FutureTask<>(myCallable);
                            //利用线程执行Task任务
                            new Thread(stringFutureTask).start();
                            //接受结果FutureTask.get会发生阻塞情况
                            System.out.println(stringFutureTask.get());
    
                            System.out.println("MyCallable执行完毕,返回值结果正确接收~");
                        }
                    }

             调用Callable的第二种实现方案:

                    public static void main(String[] args) throws ExecutionException, InterruptedException {
                        MyCallable myCallable=new MyCallable();
                        //创建一个线程池
                        ExecutorService executorService = Executors.newFixedThreadPool(3);
                        //创建线程执行任务,接受任务结果
                        Future<String> future = executorService.submit(myCallable);
                        //接受返回值
                        System.out.println(future.get(2000,TimeUnit.MILLISECONDS));
                        System.out.println("方式二,线程池:MyCallable执行完毕,返回值结果正确接收~");
                        //停止线程池
                        executorService.shutdown();
                    }

                Future.get()                      方法获取任务执行结果,该方法如果没有返回时,暂时处于阻塞状态
                Future.get(Long timeOut,TimeUnit timeUnit)          可以设置超时时间
                Future.boolean isDone()                  如果线程结束,无论是正常结束还是任务终止都会返回true
                Future.boolean isCanceller()                 如果任务完成前被取消则返回true
                Future.boolean cancel(boolean flag)            方法参数如果传入为true代表中断任务,如果任务中断成功,则返回值为true,如果失败则为false

       Future提供三种功能:1.中断任务cancel(true)        2.判断任务是否执行完成isDone()        3.获取任务执行后的结果get()

    //中断任务
                    boolean cancel = future.cancel(true);
                    if(cancel){
                        System.out.println("中断任务成功~");
                    }else{
                        //接受返回值
                        System.out.println(future.get(2000,TimeUnit.MILLISECONDS));
    
                    }

    如果手写Future模式应该怎么样定义?

    wait负责阻塞和notify负责唤起阻塞线程

                    public class MyFuture {
                        //FLAG相当于数据标识,如果放入数据成功,则返回为true,否则返回为false
                        private static boolean FLAG=false;
                        private String data;
    
                        public synchronized void setData(String data) throws InterruptedException {
                            Thread.sleep(2000);
                            //赋值操作
                            this.data = data;
                            FLAG=true;
                            //唤起
                            notify();
                        }
    
                        public synchronized String getData() {
                            //如果获取数据失败
                            if(!FLAG){
                                try {
                                    wait();
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                }
                            }
                            return data;
                        }
    
                        public static void main(String[] args) {
                            MyFuture future=new MyFuture();
                            new Thread(()->{
                                try {
                                    future.setData("张三");
                                    System.out.println(future.getData());
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                }
                            }).start();
                        }
                    }
  • 相关阅读:
    字典常用操作复习
    列表常用方法复习
    爬虫流程复习
    协程解决素数
    yield 复习
    多线程复习2
    多线程复习1
    异常 巩固3
    logging日志基础示例
    2019最新百度网盘不限速下载教程
  • 原文地址:https://www.cnblogs.com/chx9832/p/12551536.html
Copyright © 2011-2022 走看看