先由一个例子引入什么是Future Pattern。
【例子】我去蛋糕店取蛋糕,下订单后,店员请我"请在天黑后再来店里取货",并给我一张提货单。在店员做蛋糕的时候,我可以陪MM逛街,看电影等,而不需要在蛋糕店外等候。黄昏后,我拿着这张提货单到蛋糕店来取货。店员说了声"先生,你的蛋糕好了",并把蛋糕给了我。
上面的例子就是Future Pattern的一个直观的使用例子。
上面就是一此完整的Future Pattern的运行模式。
下面提供一段范例程序。
首先介绍一下范例程序包含的一些类和接口:
运行结果如下:
对结果的分析:
可以看到最开始Main线程开始后,三个请求线程,开始后马上就结束了。这一过程就好像有三个人去蛋糕店订蛋糕,立刻就拿到了提货单。这一过程体现在输出结果的1到7行。
这之后,三个人分别忙自己的事情去了,假设时间刚好为一下午(反映在程序中就是Main线程sleep的那2000毫秒),这期间蛋糕店的师傅也没闲着,加紧做蛋糕,最先做谁的蛋糕也完全随机,结果反映就是先做C,在A,最后是B。也就是输出结果的8到14行。
三个玩够了,肚子饿了。想起来蛋糕店还有蛋糕呢,于是去取蛋糕。这个时候蛋糕已经做完了,三个人顺利取走蛋糕回家。也就是结果的最后15到19行。
从程序来看,Future Pattern有几个必要的参与者。
扩展思考:
1.吞吐量由提高吗?
对于我们的程序,对于单CPU的系统,CPU处理的总时间是一样的,因为计算机宏观并行,微观串行所决定。然而,如果加上I/O处理,如对硬盘的访问,大部分时间CPU只是等待工作结束而已,对于CPU,这部分时间是空闲时间,若能把空闲时间给其他的线程使用,那么相当于也提高了计算机的吞吐量。
2.响应性的提高?
对于此种模式,你不必等待某个工作的完成,你可以串行的干一些其他的工作。
3.实现异步?
使用此模式,通过"稍后在设置真正的处理结果",做到异步方法调用的返回值。
4.分离"准备返回值"和"使用返回值"
建立RealData的操作就是"准备方法的返回值",而调用getContent方法则是为了"使用方法的返回值"。如此,将调用方法的一系列动作,像慢动作播放一样逐一拆解,就可以把多线程当做道具来使用了。
Future设计模式是很有意思的一个模式,今天学习时很是喜欢,摘录一些段落加上自己的理解记录下来,与大家分享。
大部分摘自《Java多线程设计模式详解》一书。