如果主线程向别的线程发送请求,别的线程处理完请求后还要返回给主线程一个结果,那么这种状况下应该使用Future Pattern。
示例:Host类中的request方法发送请求,这个方法中启动了一个线程,线程中首先建立实例RealData,RealData的构造中显示一组数据(耗时),然后设置一个属性content;request中的线程再将一个FutureData实例(Host的属性)future的属性realdata的值改为刚建立的RealData;最后request方法返回future。在Main中,要想通过future获取realdata的content,必须等到future设置了realdata以后才可以获取。所以,Main中让host调用request方法后,request建立realdata到设置future的RealData域为realdata的过程中,Main已经获得了future,但future的内容并没有改变,这是Main获取内容的时候就会等待,当Host中的线程跑完后,Main已经获得的future就发生了改变,这时Main又被激活,继续执行。
public interface Data {
public abstract String getContent();
}
public class RealData implements Data{
private final String content;
public RealData(int count,char c){
System.out.println(" making realdata("+count+" , "+c+")Begin");
char[] buffer=new char[count];
for(int i=0;i<count;i++){
buffer[i]=c;
try{
Thread.sleep(300);
}catch(InterruptedException e){
e.printStackTrace();
}
}
System.out.println(" making realdata("+count+" , "+c+")End");
content=new String(buffer);
}
@Override
public String getContent() {
return content;
}
}
RealData是建立一个真实数据的过程。
public class FutureData implements Data{
private RealData realdata=null;
private boolean ready=false;//设置数据后才可以获取内容,并且只能设置一次数据
public synchronized void setRealData(RealData realdata){
if(ready){
return; //balk
}
this.realdata=realdata;
this.ready=true;
notifyAll();
}
@Override
public synchronized String getContent() {
while(!ready){
try{
wait();
}catch(InterruptedException e){
e.printStackTrace();
}
}
return realdata.getContent();
}
}
FutureData中有一个RealData的实例域,它获取的数据就是这个域中的内容。
public class FutureData implements Data{
private RealData realdata=null;
private boolean ready=false;//设置数据后才可以获取内容,并且只能设置一次数据
public synchronized void setRealData(RealData realdata){
if(ready){
return; //balk
}
this.realdata=realdata;
this.ready=true;
notifyAll();
}
@Override
public synchronized String getContent() {
while(!ready){
try{
wait();
}catch(InterruptedException e){
e.printStackTrace();
}
}
return realdata.getContent();
}
}
public class Host {
public Data request(final int count,final char c){
System.out.println(" request("+count+" ,"+c+")Begin");
final FutureData future=new FutureData(); //构建FutureData实例
new Thread(){
public void run(){
RealData realdata=new RealData(count ,c);//构建realdata,这是一个耗时的过程
future.setRealData(realdata);
}
}.start();
System.out.println(" request("+count+" ,"+c+")End");
return future;
}
}
public class Main {
public static void main(String[] args){
System.out.println("Main Begin");
Host host=new Host();
Data data1=host.request(10,'A');
Data data2=host.request(20,'B');
Data data3=host.request(30,'C');
System.out.println("Main otherJob Begin");
//try {
// Thread.sleep(2000);
//} catch (InterruptedException e) {
// e.printStackTrace();
//}
System.out.println("data1= "+data1.getContent());//主线程到这里需等待,直到data1(future)设置了realdata
System.out.println("data2= "+data2.getContent());
System.out.println("data3= "+data3.getContent());
System.out.println("Main End");
}
}
运行结果:
Main Begin
request(10 ,A)Begin
request(10 ,A)End
request(20 ,B)Begin
request(20 ,B)End
request(30 ,C)Begin
request(30 ,C)End
Main otherJob Begin
making realdata(10 , A)Begin
making realdata(30 , C)Begin
making realdata(20 , B)Begin
making realdata(10 , A)End
data1= AAAAAAAAAA
making realdata(20 , B)End
data2= BBBBBBBBBBBBBBBBBBBB
making realdata(30 , C)End
data3= CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
Main End