读《图解java多线程设计模式》总结--Future

1,从名字上看,Future就是将来的意思,可以这样理解当调用一个方法时,与其一直等待,不如先拿一个代表将来才能兑现的对象,然后等过来一段时间再通过这个对象获取真实结果。在生活中一个经常发生的例子就是提货单,我们去店铺下需求,可能不是马上能够收到我们需要的东西,这时会给你一张提货单(一个代表将来才能兑现的对象),过一段时间再拿这张提货单来提货

2,适用范围,与Thread-Per-Message相似,也是收到一个请求就启动一个线程,唯一区别是Thread-Per-Message不用关注最终处理结果,而Future是可以获取到最终的处理结果

3,实现方式,这里有几个概念,第一Client,发送请求方,第二Host,接受请求方,每一次接收一个请求都会返回一个Future对象,并启动一条新的线程来处理请求.第三VirtualData,虚拟数据,是一个接口,是Future和RealData的抽象。第四RealdData真实数据,最终处理的结果.第五Futrue将来才兑现的对象,可以通过该对象获取到最终的RealData

4,代码实现

1)定义VirtualData

package future.study;

public interface VirtualData {
    public  String geContent();
}

2)定义RealData

package future.study;

public class RealData implements  VirtualData{
   //最终结果
   public String content;

   public RealData()
   {
       content="Thread "+Thread.currentThread().getName()+" real data reuslt";
   }

   //返回最终结果
    @Override
    public String geContent() {
        return content;
    }
}

 

3)定义Future

 

package future.study;

public class Futrue implements  VirtualData {
   RealData realData=null;
//设置最终真实数据
   public synchronized  void setRealData(RealData realData)
   {
       if( this.realData!=null)
          return;
       this.realData=realData;
       notifyAll();
   }

   //返回最终真实数据
    @Override
    public synchronized String geContent() {
        while(realData==null)
        {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return realData.geContent();
    }
}

 

4)定义Host

package future.study;

public class Host {

    public VirtualData request(String client)
    {
        //收到Client请求
        System.out.println("Client "+ client+ " send request");
        Futrue futrue=new Futrue();

        //启动处理线程,生产最终数据结果,并最终结果设置到未来对象
        Thread thread=new Thread(){
            public void run()
            {
                RealData realData=new RealData();
                futrue.setRealData(realData);
            }
        };
        thread.start();
        System.out.println("Client "+ client+ " finish send request");
        return futrue;
    }
}

5) 定义Client,发送3个请求,等2秒后获取最终处理结果

package future.study;

public class Client {

    public static void main(String[] args) {
        Host host=new Host();
        VirtualData future1=host.request("Client1");
        VirtualData future2=host.request("Client2");
        VirtualData future3=host.request("Client3");

        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("Get Real Data");
        System.out.println(future1.geContent());
        System.out.println(future2.geContent());
        System.out.println(future3.geContent());

    }
}

6)运行结果,可以看到3个请求发送后,都收到一个未来才兑现对象,然后再各自通过这些未来对象获取到最终的真实结果

Client Client1 send request
Client Client1 finish send request and return future 
Client Client2 send request
Client Client2 finish send request and return future 
Client Client3 send request
Client Client3 finish send request and return future 
Get Real Data
Thread Thread-0 real data reuslt
Thread Thread-1 real data reuslt
Thread Thread-2 real data reuslt

 

5,利用Java特性实现Future模式,在java.util.concurrent包里面有一个FutureTask对整个Future模式进行了抽象,不需要自己实现线程相关的代码

1) 首先让Futrue继承FutureTask,并指明他最终返回的真实对象是RealData,这里重新定义了Future并改名为Java_Future

package future.study.java;

import future.study.RealData;
import future.study.VirtualData;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class Java_Future  extends FutureTask<RealData> implements VirtualData {

    public Java_Future(Callable<RealData> callable) {
        super(callable);
    }

    @Override
    public String geContent() {
        String content=null;
        try {
            //get方法返回的就是callable里面call方法返回的结果
            content=get().geContent();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        return content;
    }
}

 

2)修改Host并改名为Java_Host,使用上面的Java_Future

package future.study.java;

import future.study.RealData;
import future.study.VirtualData;
import java.util.concurrent.Callable;

public class Java_Host {

    public VirtualData request(String client) {
        //收到Client请求
        System.out.println("Client "+ client+ " send request");
       
       
        Java_Future future=new Java_Future(
                new Callable<RealData>() {
                    @Override
                    public RealData call() throws Exception {
                        return  new RealData();  //生产出最终真实的数据
                    }
                }

        );

       //启动处理线程,这里会触发Java_Future构造函数的里面Callable对象里面的call方法,
       //call方法执行成功,会用call方法返回结果来调用Java_Future里面的set(来源于父类)
       //方法把call方法结果保存起来,然后可以调用get(来源于父类)方法来获取到这个结果  
        new Thread(future).start(); 
        System.out.println("Client "+ client+ " finish send request and return future ");
        return future;    }
}

3)其他类不变,最终的运行结果,与之前自己实现的一样

Client Client1 send request
Client Client1 finish send request and return future 
Client Client2 send request
Client Client2 finish send request and return future 
Client Client3 send request
Client Client3 finish send request and return future 
Get Real Data
Thread Thread-0 real data reuslt
Thread Thread-1 real data reuslt
Thread Thread-2 real data reuslt

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值