java线程学习之Future模式

              Future模式的核心是异步调用。它类似于我们商品订单。像我们在网上买了个手机,当我们购买成功后,会生成此订单,此订单信息就是将来取商品的重要凭证,商品无法立即拿到要通过物流寄过来。在此期间,我们就可以接着我们自己的事,等待收货即可。它同时也像我们的Ajax请求的时候,页面是异步的进行后台处理。用户无需等待请求结果,可以继续浏览操作或操作其他内容。

Future模型时序图:

  

                                                  Future模式的主要参与者

参与者 作用
Main 系统启动,调用Client发出请求
Host 返回Data对象,并立即返回FutureData,并开启ClientThread线程装配RealData
Data 表示访问数据的接口。由FutureData和RealData实现该接口
FutureData Future数据,构造很快,但是是一个虚拟的数据,需要装配RealData
RealData 真实数据,构造函数的处理需要花费很长时间

Future模型的类图

            

       看第一个类Main

public class Main {

    public static void main(String[] args) throws InterruptedException {
        
        FutureClient fc = new FutureClient();   //先创建Client端的实例
        Data data = fc.request("请求参数");//为这个实例装载数据,此时返回的data数据。request相当于是购买商品成功,data相当于订单信息
        System.out.println("请求发送成功!");
        System.out.println("做其他的事情...");
        
        String result = data.getRequest();//调用之前收到的返回值data的getRequest()方法获取真正的结果,相当于拿着之前的订单信息去取快递
        System.out.println(result);
        
    }
}

      在这个类中,会先创建Client实例,将要处理的任务交给Client端去处理,这是立刻收到数据,但此时的是FutureData,而不是RealData。然后自己接着做的事情,最后调用之前收到的返回值data的getRequest()方法获取真正的结果(即之前request方法的处理结果)

  第二个 Host(Client端)类

 1 public class FutureClient {
 2 
 3     public Data request(final String queryStr){
 4         //1 我想要一个代理对象(Data接口的实现类)先返回给发送请求的客户端,告诉他请求已经接收到,可以做其他的事情
 5         final FutureData futureData = new FutureData();
 6         //2 启动一个新的线程,去加载真实的数据,传递给这个代理对象
 7         new Thread(new Runnable() {
 8             @Override
 9             public void run() {
10                 //3 这个新的线程可以去慢慢的加载真实对象,然后传递给代理对象
11                 RealData realData = new RealData(queryStr);
12                 futureData.setRealData(realData);
13             }
14         }).start();
15         
16         return futureData;
17     }
18     
19 }

 在这类中会先创建FutureData的实例(futureData)。将这个实例作为返回值返回给调用者。然后会创建一个新的线程并在新线程中创建RealData的实例(realData)。虽然创建RealData的实例需要花费很长时间,但是因为这个实例是在新线程中进行的,并不会影响Main类的处理。当realData创建成功后,线程会调用setRealData()方法,将其放置到futureData中。由于创建RealData会花费一些时间,所以设置futureData字段就是未来的事情了。

第三个Data接口

1 public interface Data {
2 
3     String getRequest();
4 
5 }

Data接口是表示数据访问(getContent()方法)的接口

第四个Future类:

 1 public class FutureData implements Data{
 2 
 3     private RealData realData ;
 4     
 5     private boolean isReady = false;
 6     
 7     public synchronized void setRealData(RealData realData) {
 8         //如果已经装载完毕了,就直接返回
 9         if(isReady){
10             return;
11         }
12         //如果没装载,进行装载真实对象
13         this.realData = realData;
14         isReady = true;
15         //进行通知
16         notify();
17     }
18     
19     @Override
20     public synchronized String getRequest() {
21         //如果没装载好 程序就一直处于阻塞状态
22         while(!isReady){
23             try {
24                 wait();
25             } catch (InterruptedException e) {
26                 e.printStackTrace();
27             }
28         }
29         //装载好直接获取数据即可
30         return this.realData.getRequest();
31     }
32 
33 
34 }

realData字段是用于保存稍后创建完毕的RealData实例的字段,可以通过setRealData方法设置该字段。

扫描二维码关注公众号,回复: 6193202 查看本文章

ready字段表示是否已经为realData赋值的字段。如果它为true,表示已经为realData赋值。

第五个RealData类

 1 public class RealData implements Data{
 2 
 3     private String result ;
 4     
 5     public RealData (String queryStr){
 6         System.out.println("根据" + queryStr + "进行查询,这是一个很耗时的操作..");
 7         try {
 8             Thread.sleep(5000);
 9         } catch (InterruptedException e) {
10             e.printStackTrace();
11         }
12         System.out.println("操作完毕,获取结果");
13         result = "查询结果";
14     }
15     
16     @Override
17     public String getRequest() {
18         return result;
19     }
20 
21 }

猜你喜欢

转载自www.cnblogs.com/songlove/p/10845969.html