future的原理是当你申请资源(计算资源或I/O资源)时,立即返回一个虚拟的资源,当真正使用的时候,再将虚拟的资源转化成真正的资源,相当于预获取。
Future,有点像期货市场的“期权”,是“对未来的一种凭证”,例如当我们买了某个房地产开发商的期房,交钱之后,开发商会给我们一个凭证(期权),这个凭证告诉我们等明年某个时候拿这个凭证就可以拿到我们所需要的房子,但是现在房子还没建好。我们目前手里有的只是一个虚拟的不能入住的房子(即期权),当我们要求要入住时,如果房子还没建好,那么就会阻塞,如果已经建好,那么就可以将期权换成了真正的房子,然后入住进去。
public class Client { public Data requestContent(final String name) { final FutureData futureData=new FutureData(); new Thread(){ @Override public void run() { // TODO Auto-generated method stub /** * RealData的构建很慢,在一个线程中去执行。 */ RealData realData=new RealData(name); futureData.setRealData(realData); } }.start(); //realData没有构建完成也可以返回这个对象 return futureData; } public static void main(String[] args)throws Exception { Client client=new Client(); //发送一个请求 Data data=client.requestContent("hello"); /** * 发送请求之后可以进行一些其他的操作 * 这里用sleep模拟,与此同时另一个线程在构建realData,然后赋值给futureData */ Thread.sleep(1000); //获取content,如果还没有准备好,则会阻塞 System.out.println(data.getContent()); } }
public interface Data { public String getContent(); }
public class FutureData implements Data{ private RealData realData; private boolean isReady; public synchronized void setRealData(RealData realData) { if (isReady) { return; } this.realData=realData; isReady=true; notifyAll(); } @Override public synchronized String getContent() { // TODO Auto-generated method stub while(!isReady){ try { wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return realData.getContent(); } }(4)RealData.java
public class RealData implements Data { private List<String> list; public RealData(String name) { // TODO Auto-generated constructor stub list=new ArrayList<String>(); for(int i=0;i<10000;i++){ list.add(name+i); } } @Override public String getContent() { // TODO Auto-generated method stub return list.get(1000); } }
public class RealContent implements Callable<String> { private List<String> list; public RealContent(String name) { // TODO Auto-generated constructor stub list=new ArrayList<String>(); for(int i=0;i<10000;i++){ list.add(name+i); } } @Override public String call() throws Exception { // TODO Auto-generated method stub return list.get(1000); } }(2)LearnFuture.java
public class LearnFuture { public static void main(String[] args) throws Exception{ /** * FutureTask implements RunnableFuture * * 而 RunnableFuture<V> extends Runnable, Future<V> * * 因此使用FutureTask既可以作为线程要执行的任务,又可以通过它来获取线程处理的结果 */ FutureTask<String> task=new FutureTask<String>(new RealContent("hello")); ExecutorService executorService=Executors.newFixedThreadPool(1); //发送请求 executorService.submit(task); //发送请求后,可以进行其他操作,这里用sleep模拟 Thread.sleep(1000); //获取处理的结果,如果还没有处理完,则会阻塞 System.out.println(task.get()); } }