• 13.多线程设计模式


    多线程设计模式 - Future模式

    并发设计模式属于设计优化的一部分,它对于一些常用的多线程结构的总结和抽象。与串行相比并行程序结构通常较为复杂,因此合理的使用并行模式在多线程并发中更具有意义。

    1. Future

    Future模式是多线程开发中非常常见的一种设计模式,它的核心思想是异步调用。

    这类似我们日常生活中的在线购物流程,带在购物网看着一件商品时可以提交表单,当订单完成后就可以在家里等待商品送货上门。

    或者说更形象的是我们发送Ajax请求的时候,页面是异步的进行后台处理,用户无需等待请求的结果,可以继续浏览或操作其他内容

    示例:下面示例为Future的原理实现;<br />
    说明:看类注释即可明了 不明白可以去屎

     1 //Data.java   * 首先看这个接口Data,只有一个方法getRequest(),返回String字符串.
     2   public interface Data {
     3       String getRequest();
     4   }
     5   //RealData.java   * 然后再看RealData这个类,实现了Data接口,首先他有构造函数,可以理解为一个真实的业务逻辑,比较耗时,做这个sleep我们可以想象成在处理业务逻辑.
     6   public class RealData implements Data{
     7       private String result;
     8 
     9       public RealData(String queryStr){
    10           System.out.println("根据"+queryStr+"进行查询,这是一个很耗时的操作..");
    11           try {
    12               Thread.sleep(5000);
    13           } catch (InterruptedException e) {
    14               e.printStackTrace();
    15           }
    16           System.out.println("操作完毕,获取结果");
    17           result="查询结果";
    18       }
    19 
    20       @Override
    21       public String getRequest() {
    22           return result;
    23       }
    24   }
    25 
    26   //FutureData.java* 接着再看FutureData这个类,也实现了Data接口.先看FutureData的getRequest()方法,这个方法先死循环判断boolean,如果isReady是true,就阻塞着,不然就返回RealData真的getRequest()\方法(真实的结果).
    27   //  然后再看setRealData(),判断isReady,如果是ture,直接return,如果不是就赋值RealData,并修改isReady,然后notify()..
    28   public class FutureData implements Data{
    29 
    30       private RealData realData;
    31       private boolean isReady = false;
    32 
    33       public synchronized void setRealData(RealData realData){
    34           //如果已经加载完毕就直接返回
    35           if(isReady){
    36               return;
    37           }
    38           //如果没有装载,进行装载真实对象
    39           this.realData= realData;
    40           isReady = true;
    41           //进行通知
    42           notify();
    43       }
    44 
    45       @Override
    46       public synchronized String getRequest() {
    47           //如果没有装载好,程序就一直处于阻塞状态
    48           while(!isReady){
    49               try {
    50                   wait();
    51               } catch (InterruptedException e) {
    52                   e.printStackTrace();
    53               }
    54           }
    55           //装载好直接获取数据即可
    56           return this.realData.getRequest();
    57       }
    58   }
    59   //FutureClient.java * 最后看FutureClient 这个类,最简单了,返回futureData,偷偷开了线程,看到RealData realData = new RealData(request)没有?就是开始执行业务了,然后当FutureData这个类的setRealData(RealData realData)时就通知了..
    60   public class FutureClient {
    61 
    62       public Data request(final String queryStr){
    63           //1 我想要一个代理对象(Data接口的实现类)先返回发送请求的客户端,告诉他请求已经接收到,可以做其他事情
    64           final FutureData futureData = new FutureData();
    65           //2 启动一个新的线程,去加载真实的数据,传递给这个代理对象
    66           new Thread(new Runnable(){
    67               @Override
    68               public void run() {
    69                   //3 这个新的线程可以去慢慢加载真实对象,然后传递给代理对象
    70                   RealData realData = new RealData(queryStr);
    71                   futureData.setRealData(realData);
    72               }
    73           }).start();
    74           //直接返回一个假的包装类futureData
    75           return futureData;
    76       }
    77   }
    78   //主函数
    79   public class Main {
    80 
    81     public static void main(String[] args) {
    82         FutureClient fc = new FutureClient();
    83         Data data = fc.request("请求参数");
    84         System.out.println("请求发送成功!");
    85         System.out.println("做其他的事情...");
    86 
    87         String result = data.getRequest();
    88         System.out.println(result);
    89     }
    90   }

    上面的原理你可以不用懂,当然懂最好了,可以在面试官面前吹牛逼啊..future模式这么凶残,jdk也有实现的,在java.util.concurrent,又是concurrent,这个工具类真的是强大<br />
    示例:<br />

     1 //
     2   import java.util.concurrent.Callable;
     3 
     4   public class RealData implements Callable<String> {
     5     private String Data;
     6 
     7     public RealData(String Data) {
     8         this.Data = Data;
     9     }
    10 
    11     public String call() throws Exception {
    12         //利用sleep来表示任务处理
    13         Thread.sleep(2000);
    14 
    15         return "这是处理"+Data+"结果";
    16     }
    17   }
    18   //
    19   import java.util.concurrent.ExecutorService;
    20   import java.util.concurrent.Executors;
    21   import java.util.concurrent.FutureTask;
    22 
    23   public class Main {
    24 
    25       public static void main(String[] args) throws Exception {
    26           Long start = System.currentTimeMillis();
    27 
    28           FutureTask<String> futureTask = new FutureTask<>(new RealData("hello,world"));
    29           ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(1);
    30           newFixedThreadPool.submit(futureTask);
    31 
    32           // 表示正在处理其他逻辑,或者业务
    33           Thread.sleep(1000);
    34 
    35           System.out.println("最后结果-->" + futureTask.get());
    36 
    37           Long end = System.currentTimeMillis();
    38 
    39           Long useTime = end - start;
    40 
    41           System.out.println("程序运行了-->" + useTime + "毫秒");
    42       }
    43   }
  • 相关阅读:
    SQL中 decode()函数简介
    php中foreach()的用法
    swfuploadphp上传说明
    未知,等知道什么以后再改
    php上传文件处理
    smarty中的section和foreach
    asp.net 异常:"DataBinding: 'System.Data.DataRowView'
    自定义MembershipProvider配合Asp.net 2.0 Login控件(转的,忘记哪里的了)
    地理信息中各种坐标系区别和转换总结
    asp.net异常DataRowView The type or namespace name 'DataRowView' could not be found
  • 原文地址:https://www.cnblogs.com/Mao-admin/p/9989140.html
Copyright © 2020-2023  润新知