并行设计模式属于设计优化的一部分,它是对一些常用的多线程结构的总结和抽象,与串行程序相比,并行程序的结构通常更为复杂,因此合理的使用并行模式在多线程开发中更具意义,在这里主要讲解Future、Master-Worker和生产者-消费者模糊。
一、Future设计模式
Future模式类似于商品订单,只要付完款等着商品到货即可。比如在网购时,当看到某一件商品时,就可以提交订单,当订单处理完成之后,在家里等着商品送货上门即可。或者说更形象的我们发送Ajax请求的时候,页面是异步的进行后台处理,用户无需一直等到请求结果,可以继续浏览或操作其他内容。体现了异步请求的思想。
Future设计模式主要参与者:
参与者 | 主要作用 |
Main函数 | 主要启动程序,模拟客户端Client发起请求 |
Data | 返回数据的接口 |
FutureData | 构造客户端请求的虚拟返回参数,构造很快,但是需要转配真是RealData |
RealData | 异步构造真实数据,构造慢,耗时长 |
FutureClient | 返回Data对象,立即返回FutureData,并开启ClientThread线程装配RealData |
1>Main函数的实现:
public class Main {
public static void main(String[] args) {
FutureClient futureClient = new FutureClient();
//这里会立即返回,因为获取的是FutureData,而非RealData
Data data = futureClient.request("请求参数");
System.out.println("请求发送成功...");
System.out.println("做其他的事情...");
String result = data.getRequest();
System.out.println(result);
}
}
2>Data接口实现:
public interface Data {
String getRequest();
}
3>FutureData实现
public class FutureData implements Data {
private RealData realData; //FutureData是RealData的封装
private boolean isReady = false; //是否把真实RealData构造好
public synchronized void setRealData(RealData realData) {
if (isReady) {
return;
}
this.realData = realData;
isReady = true;
notify(); //RealData已经被注入到FutureData中了,通知getResult()方法
}
@Override
public synchronized String getRequest() {
while (!isReady) {
try {
wait(); //一直等到RealData注入到FutureData中,目前处于阻塞状态
} catch (Exception e) {
e.printStackTrace();
}
}
return this.realData.getRequest();
}
}
4>RealData实现:
public class RealData implements Data {
private String result;
public RealData(String queryStr) {
System.out.println("查询条件为:" + queryStr);
// 利用sleep方法来表示RealData构造过程是非常缓慢的
try {
Thread.sleep(5000);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("操作完毕,获取结果");
result = "查询结果";
}
@Override
public String getRequest() {
return result;
}
}
5>FutureClient实现
public class FutureClient {
public Data request(final String queryStr) {
final FutureData futureData = new FutureData();
//RealData的构建很慢,所以放在单独的线程中运行
new Thread(new Runnable() {
@Override
public void run() {
RealData realData = new RealData(queryStr);
futureData.setRealData(realData);
}
}).start();
//直接先返回FutureData
return futureData;
}
}