Java多线程实现订单模式:
客户端线程向服务端发起请求后,请求处理需要较长时间处理,这个时候客户端又需要及时得到一个结果响应,这好比我们去蛋糕店订蛋糕,蛋糕往往需要几个小时才能完成,这个时候店员就会给我一个订单,说过几个小时回来取蛋糕。
摸拟场景,客户端线程向服务端发起请求获取数据内容,数据准备需要很长时间,这个时候我们可以及时返回一个虚拟数据结果,服务器端启动新线程准备数据,一段时间后客户端线程在根据虚拟数据结果来获取真实数据内容。
设计如下:
[img]http://dl2.iteye.com/upload/attachment/0087/6710/d92469d3-45e6-3c95-9f91-0eaeddf50939.png[/img]
Main:程序main类,负责发起客户端请求。
Server:服务端类,负责接收请求,创建新线程处理请求。
Data:数据接口,提供获取数据内容接口。
VistualData:虚拟数据类,实现data接口,服务端快速响应的虚拟数据结果,可以获取真实数据内容。
RealData:真实数据类,实现data接口,提供处理数据内容和存储真实数据内容。
时序图如下:
[img]http://dl2.iteye.com/upload/attachment/0087/6700/8d4855a7-8a2b-3913-ab31-b8f0d25adfcc.png[/img]
实现如下:
Main:main类发出请求
Server:服务类,处理请求
Data:data接口
VirtualData:虚拟数据类
RealData:真实数据类
执行结果如下:
客户端线程向服务端发起请求后,请求处理需要较长时间处理,这个时候客户端又需要及时得到一个结果响应,这好比我们去蛋糕店订蛋糕,蛋糕往往需要几个小时才能完成,这个时候店员就会给我一个订单,说过几个小时回来取蛋糕。
摸拟场景,客户端线程向服务端发起请求获取数据内容,数据准备需要很长时间,这个时候我们可以及时返回一个虚拟数据结果,服务器端启动新线程准备数据,一段时间后客户端线程在根据虚拟数据结果来获取真实数据内容。
设计如下:
[img]http://dl2.iteye.com/upload/attachment/0087/6710/d92469d3-45e6-3c95-9f91-0eaeddf50939.png[/img]
Main:程序main类,负责发起客户端请求。
Server:服务端类,负责接收请求,创建新线程处理请求。
Data:数据接口,提供获取数据内容接口。
VistualData:虚拟数据类,实现data接口,服务端快速响应的虚拟数据结果,可以获取真实数据内容。
RealData:真实数据类,实现data接口,提供处理数据内容和存储真实数据内容。
时序图如下:
[img]http://dl2.iteye.com/upload/attachment/0087/6700/8d4855a7-8a2b-3913-ab31-b8f0d25adfcc.png[/img]
实现如下:
Main:main类发出请求
package com.thread.order;
/**
* main类,想服务发出请求,获取请求数据
* @author Administrator
*
*/
public class Main {
/**
* main方法
* @param args
*/
public static void main(String[] args) {
System.out.println("main start...");
//创建服务
Server server = new Server();
//调用三个数据服务请求
Data data1 = server.getData('a', 2);
Data data2 = server.getData('b', 3);
Data data3 = server.getData('c', 4);
//main线程休息2秒
try {
Thread.sleep(2000);
} catch (Exception e) {
}
//输出数据内容
System.out.println("data1="+data1.getContent());
System.out.println("data2="+data2.getContent());
System.out.println("data3="+data3.getContent());
System.out.println("main end...");
}
}
Server:服务类,处理请求
package com.thread.order;
/**
* 服务类,处理服务请求
* @author Administrator
*
*/
public class Server {
/**
* 返回虚拟数据结果,启动线程处理数据内容。
* @param c
* @param count
* @return
*/
public Data getData(final char c, final int count){
final VirtualData vdata = new VirtualData();
System.out.println("start getData:"+c);
//启动新线程处理数据
new Thread(){
public void run(){
System.out.println(Thread.currentThread().getName()+".start."+c);
RealData rdata = new RealData();
rdata.setContent(c, count);//设置真实数据内容
vdata.setRealData(rdata);//设置真实数据与虚拟数据关联
System.out.println(Thread.currentThread().getName()+".end."+c);
}
}.start();
System.out.println("end getData:"+c);
return vdata;
}
}
Data:data接口
package com.thread.order;
/**
* 数据服务接口
* @author Administrator
*
*/
public interface Data {
/**
* 数据内容接口
* @return
*/
public String getContent();
}
VirtualData:虚拟数据类
package com.thread.order;
/**
* 虚拟数据类
* @author Administrator
*
*/
public class VirtualData implements Data{
//真实数据
private RealData realData;
//数据准备标准,true表示数据准备完成,false表示数据尚未准备完成
private boolean ready = false;
/**
* 设置真实数据
* 判断虚拟数据是否已经设置真实数据
* 如果没有真实数据则执行真实数据设置
* 如果有真实数据,则推出设置
* @param rdata
*/
public synchronized void setRealData(RealData rdata){
if(ready){
return;
}
System.out.println(Thread.currentThread().getName()+" set RealData");
this.realData = rdata;
this.ready = true;
notifyAll();
}
/**
* 获取数据内容
* 判断真实数据是否设置,
* 如果设置则返回真实数据内容
* 如果没有设置则线程等待其他线程设置数据
*/
@Override
public synchronized String getContent() {
while (!ready){
try {
System.out.println(Thread.currentThread().getName()+"{wait}");
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return realData.getContent();
}
}
RealData:真实数据类
package com.thread.order;
import java.util.Random;
/**
* 真实数据类
* @author Administrator
*
*/
public class RealData implements Data{
//数据内容
private String content;
private Random random = new Random();
/**
* 设置数据内容
* @param c
* @param count
*/
public void setContent(char c, int count){
char[] buffer = new char[count];
for (int i = 0; i < count; i++) {
buffer[i] = c;
try {
Thread.sleep(random.nextInt(1000));//随机休息
} catch (InterruptedException e) {
e.printStackTrace();
}
}
content = new String(buffer);
}
/**
* 获取数据内容
*/
@Override
public String getContent() {
return content;
}
}
执行结果如下:
main start...
start getData:a
end getData:a
start getData:b
Thread-0.start.a
end getData:b
start getData:c
end getData:c
Thread-1.start.b
Thread-2.start.c
Thread-0 set RealData
Thread-0.end.a
Thread-1 set RealData
Thread-1.end.b
data1=aa
data2=bbb
mian {wait}
Thread-2 set RealData
Thread-2.end.c
data3=cccc
main end...