一、 Future模式简介
Future有道翻译:n. 未来;前途;期货;将来时。我觉得用期货来解释比较合适。举个实际生活中例子来说吧,今天我女朋友过生日,我去蛋糕店准备给女朋友定个大蛋糕,超级大的那种。
“老板,我要个最大最漂亮的蛋糕”
“好,999元,先付款吧”
“这么贵!!!”想想还是买了吧,掏了钱,付了款,老板给我一张蛋糕票。
“下午过来取。下午拿这张蛋糕票过来拿蛋糕”
“纳尼,这么久”
“没有办法,你可以选择在这等,我们会马上开做,不过我建议你还是去干点别的,去买个花什么的,那样您女朋友会更开心的”
……
下午一点钟我早早的就到蛋糕店了。
“老板,我的蛋糕呢?”
“不好意思,还没做好,您稍微等一会”
“晕”
十分钟后,我终于拿我的蛋糕票取到了送给女朋友的超级大蛋糕了。
这就是Future模式,蛋糕就是我要的数据(RealData),去蛋糕店订蛋糕就是我调用取数据的方法,付完钱,我没有真的拿到蛋糕,只是一个蛋糕票(FutureData),要取数据就是拿这个蛋糕票(FutureData)取(get)蛋糕(RealData)。取的时候蛋糕可能还没有做好,你还是要等,如果做好了,你直接拿走就行了。这种模式的好处就是你不用一直在等着蛋糕出来,做蛋糕的时间你可以去做别的事。有一点就是你不能准确的知道多久能做好蛋糕,很有可能来早了,还是要等,但是没有关系,总比一直在等着强吧。
二、 代码实现
public interface ICake { String getName(); } public class RealCake implements ICake{ public RealCake(){ try { //造蛋糕好费时间的 Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } public String getName() { return "最大最好吃的蛋糕"; } } public class CakeTicket implements ICake { private RealCake cake; public synchronized String getName() { while(cake==null){ try { //还没有做好,等待... wait(); } catch (InterruptedException e) { e.printStackTrace(); } } return cake.getName(); } public synchronized void setCake(RealCake cake) { this.cake = cake; //做好了,可以取蛋糕了 notifyAll(); } } public class CakeShop { //获取蛋糕的方法 public static ICake getCake(){ //构造一个虚拟数据返回给客户,这只是个虚拟的结果,相当给了客户一张取结果的卡,但是客户最好不要 //急着取结果,因为结果数据一般需要一定时间构造,客户最好去干点别的,过一会再来取 final CakeTicket cake = new CakeTicket(); //使用一个线程去构造真实的数据,为何要用线程,因为这个资源构造比较费时 new Thread(new Runnable(){ public void run() { RealCake realData = new RealCake(); cake.setCake(realData); } }).start(); return cake; } } public class Me { public static void main(String[] args) { ICake cake = CakeShop.getCake(); System.out.println("买花去喽"); //dosomething System.out.println("蛋糕的名字:"+cake.getName()); } }
Java5提供了一个可以带返回值的线程实现,名字就叫Future,看了一下,发现也就是Future模式,可以直接用就可以了。
public static Future<RealCake> getCake(){ ExecutorService threadpool = Executors.newCachedThreadPool(); Future<RealCake> futureData = threadpool.submit(new Callable<RealCake>() { public RealCake call() throws Exception { RealCake realCake = new RealCake(); return realCake; } }); return futureData; } public static void main(String[] args) throws InterruptedException, ExecutionException { Future<RealCake> cake = CakeShop4Future.getCake(); System.out.println("买花去喽"); //dosomething System.out.println("蛋糕的名字:"+cake.get().getName()); }
三、 使用场景
一个请求要获取地图的图片,以及一些位置信息,由于地图图片的生成比较费时,那么我们利用Future模式,让一个生成地图的线程慢慢生成图片,而获取位置信息也可以同时进行,不必等到图片生成完了再去获取位置信息。
Future模式解决的问题是让本来顺序执行的事情,变成可以同时执行。