zoukankan      html  css  js  c++  java
  • Future模式理解及FutureTask应用场景

    一、 Future模式理解

    先说一下为什么要用future模式:两个任务没有必然的前后关系,如果在一个线程中串行执行,就有些浪费时间,不如让两个线程去并行执行这两个任务,执行完了到主线程去汇报就可以了。(让任务后台运行,不阻塞线程)

    则使用Future模式耗费的时间为: max(TimeofTask1,TimeofTask2)。串行的话则是TimeofTask1+TimeofTask2。

    接下来使用代码的类图:

    先贴出源码,可以先看下源码理解一下,怎么使用就成了future模式。

    Interface:

    public interface Data {
        public String getResult();
    }

    RealData:

    public class RealData implements Data{
        protected final String result;
    
        public RealData(String para) {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < 10; i++) {
                sb.append(para);
            }
            try {
                // 这里使用sleep,模拟很慢的构造RealData过程
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            result = sb.toString();
        }

      @Override
      public String getResult(){
        return result;
      }
    }

    FutureData

    // FutureData是RealData的包装
    public class FutureData implements Data {
        protected RealData realData = null;
        protected boolean isReady = false;
        public synchronized void setRealData(RealData realdata){
            if (isReady){
                return;
            }
            this.realData = realdata;
            isReady = true;
            // RealData注入完毕以后,通知getResult()
            notifyAll();
        }
    
        @Override
        public synchronized String getResult() {
            while (!isReady){
                try {
                    // 等待RealData被注入,直到被notify
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            return realData.result;
        }
    }
    View Code

    首先我们要明确,RealData是我们真正需要的数据,FutureData只是做了一层封装,可以实现在得到RealData的过程中不阻塞当前线程。

    我们重点来看FutureData,就两个方法,暂且把setRealData叫做注入数据方法,getResult是拿到最终数据方法。

    一个状态位isReady,等待RealData注入完毕,就可以getResult了。没注入完毕,则阻塞当前线程。

    有了这些信息,我们可以这样想,这个构建RealData很费时间,不如把这个构建任务扔到一个线程里去,当前线程去做其他事情。

    使用方法:

    public class FutureMainByMyself {
        public Data request(final String queryStr){
            // futureData包装了RealData
            final FutureData futureData = new FutureData();
            new Thread(){
                // RealData构建很慢,放在一个线程里慢慢去构建
                @Override
                public void run() {
                    RealData realData = new RealData(queryStr);
                    futureData.setRealData(realData);
                }
            }.start();
            return futureData;
        }
    
        public static void main(String[] args) {
            FutureMainByMyself client = new FutureMainByMyself();
            Data data = client.request("name");
            System.out.println("请求完毕");
            //这里才是真实的数据
            try {
                //这里的sleep代表了其他的业务逻辑,
                //在处理这些业务逻辑的同时,RealData被创建,从而充分利用了时间
                System.out.println(LocalTime.now());
                Thread.sleep(2000);
                System.out.println(LocalTime.now());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("数据=" +data.getResult() + " " + LocalTime.now());
    
        }
    }

    二、FutureTask应用场景和源码解析

    FutureTask使用场景上面只是大致说了一下,下面我们来举一个具体的场景:API网关。

    比方说用户打开一个订单页面:可能要查许多接口:订单信息,积分信息,退换货信息,这时候如果串行去查这么多东西,很费时间。

    这些信息是没有必要的先后关系的,所以可以做出并行的。平时我们用软件也能注意到,先出来这块信息,再出来那块信息,这就是并行去查的结果,当然也可以等所有信息都拿到,再同时返回。

    FutureTask源码解析:http://www.cnblogs.com/NoYone/p/8863083.html

  • 相关阅读:
    【cs231n笔记】assignment1之KNN
    【数据】常用卫星遥感数据下载地址整理
    ArcGIS中重采样栅格像元匹配问题
    python调用HEG工具批量处理MODIS数据
    Google Earth Engine学习资源分享
    地表温度反演的单通道方法辩异
    Android Studio无法下载sdk的问题
    Anaconda常用命令
    AMSR-E/AMSR-2数据介绍与下载
    NASA HEG tool安装心得
  • 原文地址:https://www.cnblogs.com/NoYone/p/8858051.html
Copyright © 2011-2022 走看看