1、案例分析:
你去商店买蛋糕,付完钱后蛋糕店老板会给你一张订单然后让你晚上来取,你拿到订单后接着干自己的事情了,老板让蛋糕师傅做蛋糕,等着晚上的时候你拿出订单取回蛋糕。
?
2、程序设计
?
package com.metarnet.FuturePattern; /** * 人的类,通过该类获取一个请求 * @author Administrator * */ public class Host { public Data getRequest(final int count, final char c) { System.out.println("(request count = " + count + ", c = " + c + " begin )"); final FutureData future = new FutureData(); new Thread() { @Override public void run() { RealData realData = new RealData(count, c); future.setRealData(realData); } }.start(); System.out.println("(request count = " + count + ", c = " + c + " end )"); return future; } } package com.metarnet.FuturePattern; /** * 数据接口,返回内容 * @author Administrator * */ public interface Data { public String getContent(); } package com.metarnet.FuturePattern; /** * 相当于订单类,立即返回的信息,之后通过该类的方法去获取真正的内容 * @author Administrator * */ public class FutureData implements Data { private RealData realData; private boolean ready = false; public RealData getRealData() { return realData; } public synchronized void setRealData(RealData realData) { if(realData.isReady()) { this.realData = realData; ready = true; this.notifyAll(); } } @Override public String getContent() { synchronized(this) { while(!ready) { try { wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return realData.getContent(); } } } package com.metarnet.FuturePattern; /** * 真的处理的类,在FutureData里面注册了,等内容处理完后通过FutureData调用getContent方法获取内容 * 启动新的线程去处理该类 * @author Administrator * */ public class RealData implements Data { private String content; private boolean ready = false; public RealData(int count, char c) { doParse(count, c); } @Override public String getContent() { return content; } public void doParse(int count, char c) { System.out.println("making (count = " + count + ", c = " + c + " ) begin..." ); char[] chars = new char[count]; for(int i=0; i<count; ++i) { chars[i] = c; } try { Thread.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("making (count = " + count + ", c = " + c + " ) end..." ); this.content = new String(chars); ready = true; } public boolean isReady() { return ready; } public void setReady(boolean ready) { this.ready = ready; } } package com.metarnet.FuturePattern; public class TestMain { public static void main(String[] args) { Host host = new Host(); Data f1 = host.getRequest(10, 'A'); Data f2 = host.getRequest(30, 'B'); Data f3 = host.getRequest(20, 'C'); System.out.println("main begin..."); try { Thread.sleep(2000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(f1.getContent()); System.out.println(f2.getContent()); System.out.println(f3.getContent()); System.out.println("main end..."); } }
?
?3、在获取网页信息的程序:
?
package com.metarnet.FuturePattern.URLContent; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; public class Main { public static void main(String[] args) { Retriver test = new Retriver(); try { Content content1 = test.getContent("http://www.sina.com"); Content content2 = test.getContent("http://www.yahoo.cn"); Content content3 = test.getContent("http://www.hhstu.edu.cn"); Thread.sleep(5000); saveToFile("yahoo.html", content1); saveToFile("goole.html", content2); saveToFile("hhstu.html", content3); } catch (InterruptedException e) { e.printStackTrace(); } } private static void saveToFile(String name, Content content1) { File file = new File("E:" + File.separator + "html"); if(!file.exists()) { file.mkdirs(); try { file.createNewFile(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } FileOutputStream output = null; try { output = new FileOutputStream(file + File.separator + name); output.write(content1.getBytes()); output.close(); System.out.println(name + "生成成功!"); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { if(output != null) { try { output.close(); } catch (IOException e) { e.printStackTrace(); } output = null; } } } } package com.metarnet.FuturePattern.URLContent; public interface Content { public byte[] getBytes(); } package com.metarnet.FuturePattern.URLContent; import java.io.BufferedInputStream; import java.io.DataInputStream; import java.io.EOFException; import java.io.FileInputStream; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; public class RealContentImpl implements Content { private byte[] bytes; private boolean ready = false; public RealContentImpl(String url) { doParse(url); } private byte[] doParse(String urlName) { System.out.println(Thread.currentThread().getName() + " doParse " + urlName + " begin..."); URL url = null; DataInputStream input = null; byte[] bytesTmp = new byte[1]; try { url = new URL(urlName); input = new DataInputStream(url.openStream()); int index = 0; while(true) { int c = input.readUnsignedByte(); if(bytesTmp.length <= index) { byte[] largerBuffer = new byte[bytesTmp.length * 2]; System.arraycopy(bytesTmp, 0, largerBuffer, 0, index); bytesTmp = largerBuffer; } bytesTmp[index++] = (byte)c; } } catch (EOFException e) { } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { if(input != null) { try { input.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } input = null; } if(url != null) { url = null; } } bytes = new byte[bytesTmp.length]; System.arraycopy(bytesTmp, 0, bytes, 0, bytesTmp.length); ready = true; return bytes; } @Override public byte[] getBytes() { return bytes; } public void setBytes(byte[] bytes) { this.bytes = bytes; } public boolean isReady() { return ready; } public void setReady(boolean ready) { this.ready = ready; } } package com.metarnet.FuturePattern.URLContent; public class Retriver { public Content getContent(final String url) throws InterruptedException { System.out.println("request " + url + " begin..."); final VirtualContentImpl content = new VirtualContentImpl(); new Thread() { @Override public void run() { RealContentImpl real = new RealContentImpl(url); content.setReal(real); } }.start(); return content; } } package com.metarnet.FuturePattern.URLContent; public class VirtualContentImpl implements Content { private boolean ready = false; private RealContentImpl real; @Override public byte[] getBytes() { synchronized(this) { if(!ready) { try { wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return real.getBytes(); } } public RealContentImpl getReal() { return real; } public synchronized void setReal(RealContentImpl real) { if(real.isReady()) { this.real = real; ready = true; this.notifyAll(); } } }?
?