并行程序设计模式
并行设计模式属于设计优化的一部分,它是对一些常用的多线程结构的总结和抽象。与串行程序相比,并行程序的结构通常更为复杂。因此,合理的使用并行模式在多线程开发中,更具有积极意义。本文中主要介绍Future模式、Master-Worker模式、GuardedSuspeionsion模式、不变模式和生产者-消费者模式。
**1Future模式**
Future模式有点类似商品订单。比如在进行网上购物时,当看中某一件商品时,就可以提交订单,当订单处理完毕后,便可以等在家里等待商品送货上门。卖家根据订单从仓库里取货,并配送到客户手里。大部分情况下,商家对订单的处理并不那么快,又是甚至需要几天时间,而在这段时间内,客户完全不必傻傻等在家里,可以出门处理其他事物。
将此例类推到程序设计中,当某一程序提交一个请求,期望得到一个答复。但非常不幸的是,服务程序对这个请求的处理可能很慢,比如,这个请求可能时通过互联网http或者webservice等并不太搞笑的方式调用的。在传统的单线程环境下,调用函数时同步的,也就是说 它必须等到服务返回结果后,才能进行其他处理。而在Future模式下,调用方式改为异步,而原先等待返回的时间段,在主调用函数中,则可用与处理其他事物,如图所示,显示了一段传统调用的流程
图1 传统串行程序调用流程
如图1所示,客户端发出call请求,这个请求需要相当长的一段时间才能返回。客户端一直等待,知道数据返回,随后,再进行其他任务处理。而使用Future模式替换原的实现方式,才可以进行其他调用过程。
图2显示了一个广义Future模式的实现,从Data_future对象可以看出,虽然call本身仍然需要很长一段时间来处理程序。但是,服务程序不等数据处理完成便离级返回客户端一个伪造的数据(相当于商品的订单,而不是商品本身),实现了Future模式的客户端拿到这个返回结果后,并不急于对其进行处理,而是调用了其他业务逻辑,充分利用了等待时间,这就是Future模式的核心所在。再完成了其他业务逻辑的处理后,最后再使用返回比较满的Future数据。这样,在整个调用过程中,就不存在所谓的等待,充分利用了所有的时间片段,从而让提高;额系统的响应速度。
Futrure模式流程图
Future模式的主要参与者
参与者 | 作用 |
---|---|
Main | 系统启动,调用Client发出请求 |
Client | 返回Data对象,并离级返回FutureData,并开启ClientThread线程装配RealData |
Data | 返回数据的接口 |
FutureData | Future数据,构造很快,但是是一个虚拟的数据,需要装配RealData |
RealData | 真实的数据,其构造是比较慢的 |
2 Furture模式的代码实现
(1)Main函数的实现
public static void main(String[] args) {
Client client = new Client();
Data name = client.request("name");
System.out.println("请求完毕");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(name.getReuslt());
}
(2)Client的实现
Client主要实现了获取FutureData,开启构造RealData的线程,并在接受请求后,很快的返回FutureData:
public class Client {
public Data request(final String queryStr){
final FutureData futureData = new FutureData();
new Thread(){
@Override
public void run(){
RealData realData = new RealData();
futureData.setRealData(realData);
}
}.start();
return futureData;
}
}
(3) Data的实现
Data是一个接口,提供了getResult()方法。无论FutureData或者RealData都实现了这个接口:
public interface Data {
public String getReuslt();
}
(4)FutureData的实现
FutureData实现了一个快速返回的RealData包装。但他只是一个包装,或者说是一个RealData的虚拟实现。因此,它可以很快的=被构造并返回。当使用FutureData的个体Result()方法时,程序会阻塞,等待RealData被注入到程序中,才使用RealData的getResult()方法返回。
注意:FutureData时Future模式的关键,它实际时一个真实数据RealData的代理,封装了获取RealData的等待过程。
public class FutureData implements Data {
//FutureData时RealData的包装
protected RealData realData = null;
protected boolean isReady = false;
public synchronized void setRealData(RealData realData) {
if (isReady) {
return;
}
this.realData = realData;
isReady = true;
//RealData已经被注入,通知个体Result()
notifyAll();
}
@Override
//会等待RealData构造完成
public synchroized String getReuslt() {
while (!isReady) {
try {
//一直等待,知道RealData构造完成
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return realData.getReuslt();
}
}