13.多线程设计模式 - Future模式

多线程设计模式 - 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   }

猜你喜欢

转载自www.cnblogs.com/Mao-admin/p/9989140.html