Future模式是一种很是常见的设计模式,其核心思想就是异步调用。设计模式
参与者 | 做用 | 备注 |
---|---|---|
Main | 系统启动,调用client发出请求 | 能够看作是一个应用 |
client | 用于返回Data对象,当即返回FutureData,并开启一个线程装配RealData | |
Data | 返回数据的接口 | |
FutureData | FutureData实现了Data接口,构造很快,是一个虚拟数据,须要装配RealData真实数据 | 也能够看作是构造一个空的Data对象,按字面意思来看就是未来的数据,尚未...,当客户端须要使用数据时须要设置成RealData对象 |
RealData | 真实数据,起构造可能会比较慢,RealData也实现了Data接口 | 这个数据才是Main应用须要的 |
/** * Created with IntelliJ IDEA. * User: * Date: 2018/12/29 * Time: 下午6:47 * Description: Data接口有两个重要的实现,FutureData和RealData,RealData表明的是真实数据,FutureData是真实数据的代理或者说是包装 */ public interface Data { String getResult(); }
/** * Created with IntelliJ IDEA. * User: * Date: 2018/12/29 * Time: 下午6:44 * Description: 实现Data接口,其功能是对RealData进行包装、代理,在FutureClient请求Data数据时,将当即返回一个包装好的虚拟数据(RealData的虚拟数据) */ public class FutureData implements Data { //既然FutureData是RealData对象的包装,那么久应该有一个对象的引用 private RealData realData = null; //标注真实数据是否准备好 private boolean isReady = false; //取数据时,若是RealData还没注入数据,则将阻塞等待 private final ReentrantLock lock = new ReentrantLock(); private final Condition condition = lock.newCondition(); public void setRealData(RealData realData) { while (isReady) { //数据已经准备好,直接退出 return; } lock.lock(); try { this.realData = realData; this.isReady = true; //数据已经准备,通知阻塞在getResult()上的请求 condition.signal(); } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } } /** * 获取真实数据,若是RealData代理对象没有准备好数据,则阻塞 * * @return */ public String getResult() { lock.lock(); try { while (!isReady) { //释放锁,同时阻塞 condition.await(); } } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } return realData.result; } }
/** * Created with IntelliJ IDEA. * User: zhouyonggui * Date: 2018/12/29 * Time: 下午6:54 * Description: RealData是最终须要使用的数据,须要返回给FutureData */ public class RealData implements Data { protected String result = null; /** * 在这个过程当中,模拟数据包装 * * @return */ public RealData(String param) { StringBuffer sb = new StringBuffer(); //假设须要很长时间的业务处理 for (int i = 0; i < 10; i++) { sb.append(param); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } } result = sb.toString(); } public String getResult() { return result; } }
接下来就是client,内部主要实现了FutureData,并开启一个线程去构造RealData。在接受请求后,先返回一个FutureData对象,此时FutureData内部并无真实数据,在须要使用数据时须要等待RealData构造完成,此时若是数据还没有准备好,则将阻塞直到有数据返回。app
/** * Created with IntelliJ IDEA. * User: zyg * Date: 2019/1/2 * Time: 下午9:12 * Description:FUture客户端主要负责获取FutureData,并异步起一个线程,构造RealData */ public class Client { public Data request(final String queryStr) { final FutureData future = new FutureData(); new Thread(new Runnable() { public void run() { RealData realData = new RealData(queryStr); future.setRealData(realData); } }).start(); return future; } }
最后是咱们的Main应用,她主要是负责调用client发起请求,并消费返回的数据。异步
/** * Created with IntelliJ IDEA. * User: zyg * Date: 2019/1/2 * Time: 下午9:21 * Description: */ public class Main { public static void main(String[] args) { Client client = new Client(); //客户端发起请求 Data data = client.request("杨幂"); System.out.println("客户端请求完毕!"); //模拟其余业务 try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } //使用真实数据 System.out.println("数据=" + data.getResult()); } }