4.1.1 Future模式

核心思想

調用方式爲異步,去除了主函數中的等待時間,主函數可去處理其他任務,如圖:

代碼實現

參與者 作用
Main 主函數,調用Client發出請求
Client 返回Data對象,立即返回FutureData,並開啓ClientThread線程裝配RealData
Data 返回數據的接口
FutureData 虛擬數據,構造很快
RealData 真實數據,構造較慢



Future模式結構圖


代碼示意:

public static void main(String[] args)
{
     Client client = new Client();

     //立即返回,得到FutureData
     Data data=client.request("name");
     System.out.println("請求完畢");

     //用sleep代表執行其他業務邏輯
     Thread.sleep(2000);

     //使用真實數據RealData
     System.out.println(data.getResult());
}

//Data接口
public interface Data
{
     public String getResult();
}

//Client類
public class Client
{
     public Data request(String str)
     {
          FutureData fd = new FutureData();

          //RealData構造很慢,單獨開線程構造
          new Thread()
          {
               public void run()
               {
                    RealData rd = new RealData(str);
                    fd.setRealData(rd);
               }
          }.start();
          return fd;
     }
}

//FutureData類
public class FutureData implements Data
{
     //FutureData是對RealData的包裝
     protected RealData rd = null;

     protected boolean isReady=false;
     public synchronized void setRealData(RealData rd)
     {
          if(isReady)
          {
               return;
          }
          this.rd=rd;
          isReady=true;
          notifyAll();
     }

     //會等待RealData構造完成
     public synchronized String getResult()
     {
          while(!isReady)
          {
               //此類中可能有其他多線程任務,被喚醒的原因不一定是RealData構造完成,所以需要循環判斷isReady是否真的構造完成
               wait();
          }
          return rd.getResult();
     }
}

//RealData類
public class RealData implements Data
{
     private String result=null;
     public RealData()
     {
          //構造數據,假設很慢
          result = new String("xxxxxx");
     }

     public String getResult()
     {
          return result;
     }
}

JDK內置實現

JDK內置實現

想要異步執行的業務邏輯放在call()方法內

代碼示意:

public class RealData implements Callable<String>
{
     private String para;
     public RealData(String para)
     {
          this.para=para;
     }

     //真實業務邏輯
     @Override
     public String call()
     {
          //構造數據,假設很慢
          return new String("xxxx");
     }
}

public class Main
{
     public static void main(String[] args)
     {
          FutureTask<String> future = new FutureTask<String>(new RealData("a"));
          ExecutorService exe = Executors.newFixedThreadPool(1);

          //開啓線程執行RealData的call()方法,相當於2中的client.request()
          exe.submit(future);
          System.out.println("請求完畢");

          //用sleep代表執行其他業務邏輯
          Thread.sleep(5000);

          //使用真實數據,相當於2中的data.getResult(),如果call()沒有執行完,依然會等待
          System.out.println(future.get());
     }
}
發佈了42 篇原創文章 · 獲贊 10 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章