自己动手敲future模式例子
1.future设计模式简介:
future设计模式的核心思想是异步调用。其理念应该跟ajax差不多,就是希望在等一个耗时比较长的操作的期间,做其他操作,然后其他操作做完了,回来再处理这个耗时长的操作的结果。这样业务完成的效率高一些。举个现实生活中的例子:你现在要煮饭炒菜,那首先,你肯定是可以先煮饭,用电饭锅慢慢煮。然后,你就可以去炒菜了。炒完菜后,饭也差不多煮熟了,等几分钟就马上开吃了!一边煮饭一边炒菜,肯定比先煮完饭再炒菜快,所以Future模式的好处就在这里。
2.future设计模式实现时序图:
通过看以下时序图,来了解future设计模式的具体实现思路:
从图中可以看到,main方法一开始就请求了数据,但是这时FutureClient返回的是一个FutureData对象。简单解释下:FutureData跟RealData都是Data接口的实现类,因此都有相同的方法,只是FutureData里面不包含真正的数据,等RealData来填充(这里可能比较难理解,稍后看代码就应该清楚)。
main方法深知现在拿到的Data对象其实是不包含具体的数据的,而且这个具体的数据要等一段时间才有。因此main方法继续去做其他事情。而与此同时,futureClient默默地开了一个线程,去获取真正的Data对象,并且填充到FutureData对象里。
main方法完成其他事情了,回头过来再取上面的FutureData数据时,其实这个时候FutureData已经填充好了真正的Data数据了,FutureData就直接调RealData的相应的方法,把结果直接转发回给main方法。
这样,通过这个设计,main方法在等待数据的同时,也把其他事情先做完了。这样,main方法完成任务的时间将会缩短一些。
3.代码例子:
下面代码的场景是:一个人拿了一头猪去给屠夫宰,这个人把猪交给屠夫后,先去买菜了,回来再拿回猪肉。
main方法:
/**
* 测试场景:先把猪给了屠夫去宰。屠夫可能需要用3秒中才宰完。在这三秒内可以先去干其他事情,回来再把猪肉拿走。
*
* @author Owen
* create time:2018/9/11 18:13
*/
public class TestFutureButcher {
public static void main(String[] args) {
ButcherClient client = new ButcherClient();
Butcher butcher = client.getButcher(new Pig("一头肥猪", 3));
System.out.println("把肥猪交给了屠夫宰。"+ LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
System.out.println("先去其他地方买点菜。。");
Pig pig = butcher.getPig();
System.out.println("从屠夫手里拿回猪肉.."+ pig.getKilledTime().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
}
}
client类:
public class ButcherClient{
public Butcher getButcher(Pig pig){
Butcher butcher = new FutureChinaButcher();
new Thread(()->{
ChinaButcher chinaButcher = new ChinaButcher(pig);
((FutureChinaButcher) butcher).setChinaButcher(chinaButcher);
}).start();
return butcher;
}
}
FutureData类:
/**
* 中国屠夫的封装类,此类本身不包含具体的杀猪逻辑,只是
*
* @author Owen
* created time:2018/9/11 14:38
*/
public class FutureChinaButcher implements Butcher{
private ChinaButcher chinaButcher;
private CountDownLatch lock = new CountDownLatch(1);
public FutureChinaButcher() {
}
public void setChinaButcher(ChinaButcher chinaButcher) {
if(chinaButcher!=null){
this.chinaButcher = chinaButcher;
lock.countDown();
}
}
@Override
public Pig getPig() {
try {
lock.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
return chinaButcher.getPig();
}
}
RealData类:
/**
* 屠夫接口的实现类:中国屠夫
* @author Owen
* */
public class ChinaButcher implements Butcher{
private Pig pig;
/**
* 当初始化对象时,就直接执行杀猪任务,这里就简单地休眠3秒钟,然后赋值杀猪时间。
* */
public ChinaButcher(Pig pig){
try {
Thread.sleep(3000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
pig.setKilledTime(LocalDateTime.now());
this.pig = pig;
}
@Override
public Pig getPig() {
return pig;
}
}
Data接口:
/**
* 屠夫接口,提供getPig方法。
* @author Owen
* */
public interface Butcher {
Pig getPig();
}
运行结果: