先由一个例子引入什么是Future Pattern。
【例子】我去蛋糕店取蛋糕,下订单后,店员请我"请在天黑后再来店里取货",并给我一张提货单。在店员做蛋糕的时候,我可以陪MM逛街,看电影等,而不需要在蛋糕店外等候。黄昏后,我拿着这张提货单到蛋糕店来取货。店员说了声"先生,你的蛋糕好了",并把蛋糕给了我。
上面的例子就是Future Pattern的一个直观的使用例子。
- 假设有一个执行起来要花很久的方法(如做蛋糕),我们不需要等待结果完全出来了(蛋糕做好),而是获取一张替代的"提货单"。获取提货单不需要太长的时间,这个提货单就是Future参与者。
- 获取Future参与者的线程,会在事后再去执行结果,就好像拿着提货单取蛋糕一样。如果已经有执行结果了,就马上拿到数据。如果还没有,则继续等待到执行结果完全出来为止。
上面就是一此完整的Future Pattern的运行模式。
下面提供一段范例程序。
首先介绍一下范例程序包含的一些类和接口:
- Main 说明:对Host送出请求,获取数据的类。
- Host 说明:对请求返回FutureData的类。
- Data 说明:表达数据访问方式的接口,FurureData与RealData都实现了这个接口。
- FurureData说明:RealData的提货单类,而RealData实例则有其他线程建立。
- RealData说明:表达实际数据的类,执行构造器要花一定的时间。
运行结果如下:
对结果的分析:
可以看到最开始Main线程开始后,三个请求线程,开始后马上就结束了。这一过程就好像有三个人去蛋糕店订蛋糕,立刻就拿到了提货单。这一过程体现在输出结果的1到7行。
这之后,三个人分别忙自己的事情去了,假设时间刚好为一下午(反映在程序中就是Main线程sleep的那2000毫秒),这期间蛋糕店的师傅也没闲着,加紧做蛋糕,最先做谁的蛋糕也完全随机,结果反映就是先做C,在A,最后是B。也就是输出结果的8到14行。
三个玩够了,肚子饿了。想起来蛋糕店还有蛋糕呢,于是去取蛋糕。这个时候蛋糕已经做完了,三个人顺利取走蛋糕回家。也就是结果的最后15到19行。
从程序来看,Future Pattern有几个必要的参与者。
- Client(委托人)参与者,反映在程序中就是想Host发送请求的参与者,并得到VirtualData参与者,作为这个请求的结果(返回值),在实例程序中就是Main类。
- Host(处理人)参与者,建立新的线程,开始建立RealData参与者,另一方面会对Client参与者,以(VirtualData参与者的形式)返回Future参与者。新的线程建立出来RealData后,会对Future参与者设置RealData参与者。示例Host就是Host。
- VirtualData(虚拟数据)参与者,用来统一代表Future参与者和RealData参与者。在示例中就是Data接口。
- RealData(实际数据)参与者,表示实际的数据,建立需要花一些时间,示例中RealData就是RealData。
- Future(期货)参与者,Future是Host参与者传递给Client参与者,当做是RealData参与者"提货单"使用的参与者。Future参与者相对于Client参与者而言,可以进行VirtualData参与者的行为。
扩展思考:
1.吞吐量由提高吗?
对于我们的程序,对于单CPU的系统,CPU处理的总时间是一样的,因为计算机宏观并行,微观串行所决定。然而,如果加上I/O处理,如对硬盘的访问,大部分时间CPU只是等待工作结束而已,对于CPU,这部分时间是空闲时间,若能把空闲时间给其他的线程使用,那么相当于也提高了计算机的吞吐量。
2.响应性的提高?
对于此种模式,你不必等待某个工作的完成,你可以串行的干一些其他的工作。
3.实现异步?
使用此模式,通过"稍后在设置真正的处理结果",做到异步方法调用的返回值。
4.分离"准备返回值"和"使用返回值"
建立RealData的操作就是"准备方法的返回值",而调用getContent方法则是为了"使用方法的返回值"。如此,将调用方法的一系列动作,像慢动作播放一样逐一拆解,就可以把多线程当做道具来使用了。
Future设计模式是很有意思的一个模式,今天学习时很是喜欢,摘录一些段落加上自己的理解记录下来,与大家分享。
大部分摘自《Java多线程设计模式详解》一书。
分享到:
相关推荐
Future设计模式实现(实现类似于JDK提供的Future).mp4 Future源码解读.mp4 ForkJoin框架详解.mp4 同步容器与并发容器.mp4 并发容器CopyOnWriteArrayList原理与使用.mp4 并发容器ConcurrentLinkedQueue原理与使用....
第43节Future设计模式实现(实现类似于JDK提供的Future)00:19:20分钟 | 第44节Future源码解读00:29:22分钟 | 第45节Fork/Join框架详解00:28:09分钟 | 第46节同步容器与并发容器00:18:44分钟 | 第47节并发容器...
第16章 多线程——Java中的并发协作 343 16.1 线程的基本知识 343 16.1.1 多线程编程的意义 343 16.1.2 定义自己的线程 344 16.1.3 创建线程对象 345 16.1.4 启动线程 347 16.1.5 同时使用多个线程 ...
第43节Future设计模式实现(实现类似于JDK提供的Future)00:19:20分钟 | 第44节Future源码解读00:29:22分钟 | 第45节Fork/Join框架详解00:28:09分钟 | 第46节同步容器与并发容器00:18:44分钟 | 第47节并发容器...
第43节Future设计模式实现(实现类似于JDK提供的Future)00:19:20分钟 | 第44节Future源码解读00:29:22分钟 | 第45节Fork/Join框架详解00:28:09分钟 | 第46节同步容器与并发容器00:18:44分钟 | 第47节并发容器...
第43节Future设计模式实现(实现类似于JDK提供的Future)00:19:20分钟 | 第44节Future源码解读00:29:22分钟 | 第45节Fork/Join框架详解00:28:09分钟 | 第46节同步容器与并发容器00:18:44分钟 | 第47节并发容器...
10.3.3 带有多个except的try语句 10.3.4 处理多个异常的except语句 10.3.5 捕获所有异常 10.3.6 “异常参数” 10.3.7 在应用使用我们封装的函数 10.3.8 else子句 10.3.9 finally...
10.3.3 带有多个except的try语句 10.3.4 处理多个异常的except语句 10.3.5 捕获所有异常 10.3.6 “异常参数” 10.3.7 在应用使用我们封装的函数 10.3.8 else子句 10.3.9 finally...