亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

老生常談java中的Future模式

發布時間:2020-10-26 10:20:50 來源:腳本之家 閱讀:194 作者:jingxian 欄目:編程語言

jdk1.7.0_79

本文實際上是對上文《簡單談談ThreadPoolExecutor線程池之submit方法》的一個延續或者一個補充。在上文中提到的submit方法里出現了FutureTask,這不得不停止腳步將方向轉向JavaFuture模式。

Future是并發編程中的一種設計模式,對于多線程來說,線程A需要等待線程B的結果,它沒必要一直等待B,可以先拿到一個未來的Future,等B有了結果后再取真實的結果。

ExecutorService executor = Executors.newSingleThreadExecutor();
Future<String> future = executor.submit(callable); //主線程需要callable線程的結果,先拿到一個未來的Future
System.out.println(future.get()); //有了結果后再根據get方法取真實的結果,當然如果此時callable線程如果沒有執行完get方法會阻塞執行完,如果執行完則直接返回結果或拋出異常

也就是說,Future它代表一個異步計算的結果。

老生常談java中的Future模式

上面就代表了Future模式的執行原理,根據網上的例子,我們可以來自己實現一個Future模式。

package com.future;

/**
 * 數據結果
 * Created by yulinfeng on 6/18/17.
 */
public interface Data {
 String getResult() throws InterruptedException;
}
package com.future;

/**
 * 結果的真實計算過程
 * Created by yulinfeng on 6/18/17.
 */
public class RealData implements Data {
 protected String data;

 public RealData(String data) {
  try {
   System.out.println("正在計算結果");
   Thread.sleep(3000);  //模擬計算
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
  this.data = data + “ world”;
 }

 public String getResult() throws InterruptedException {
  return data;
 }
}
package com.future;

/**
 * 真實結果RealData的代理
 * Created by yulinfeng on 6/18/17.
 */
public class FutureData implements Data {
 RealData realData = null; //對RealData的封裝,代理了RealData
 boolean isReady = false; //真實結果是否已經準備好

 public synchronized void setResultData(RealData realData) {
  if (isReady) {
   return;
  }
  this.realData = realData;
  isReady = true;
  notifyAll(); //realData已經被注入到了futureData中,通知getResult方法
 }

 public synchronized String getResult() throws InterruptedException {
  if (!isReady) {
   wait();  //數據還未計算好,阻塞等待
  }
  return realData.getResult();
 }
}
package com.future;

/**
 * Client主要完成的功能包括:1. 返回一個FutureData;2.開啟一個線程用于構造RealData
 * Created by yulinfeng on 6/18/17.
 */
public class Client {

 public Data request(final String string) {
  final FutureData futureData = new FutureData();

  /*計算過程比較慢,單獨放到一個線程中去*/
  new Thread(new Runnable() {

   public void run() {
    RealData realData = new RealData(string);
    futureData.setResultData(realData);
   }
  }).start();

  return futureData; //先返回一個“假”的futureData
 }
}
/**
 * 負責調用Client發起請求,并使用返回的數據。
 * Created by yulinfeng on 6/18/17.
 */
public class Main {
 public static void main(String[] args) throws InterruptedException {
  Client client = new Client();
  System.out.println("準備計算結果");
  Data data = client.request("hello"); //立即返回一個“假”的futureData,可以不用阻塞的等待數據返回,轉而執行其它任務
  System.out.println("執行其它任務");
  Thread.sleep(3000);  //模擬執行其它任務
  System.out.println("數據的計算結果為:" + data.getResult());
 }
}

仔細閱讀以上程序對Future模式的實現不難發現,Future模式是異步請求和代理模式的結合。當然在JDK中已經為我們實現好了Future模式。

修改RealData類:

package com.future;

import java.util.concurrent.Callable;

/**
 * 結果的真實計算過程
 * Created by yulinfeng on 6/18/17.
 */
public class RealData2 implements Callable<String> {
 protected String data;

 public RealData2(String data) {
  this.data = data;
 }
 public String call() throws Exception {
  try {
   System.out.println("正在計算結果");
   Thread.sleep(2000);  //模擬計算結果
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
  this.data = data + " world";
  return data;
 }
}

修改Main測試類:

package com.future;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

/**
 * 負責調用Executor的submit,并使用返回的數據。
 * Created by yulinfeng on 6/18/17.
 */
public class Main2 {

 public static void main(String[] args) throws InterruptedException, ExecutionException {
  ExecutorService client = Executors.newSingleThreadExecutor(); //類似Client
  System.out.println("準備計算結果");
  Future<String> data = client.submit(new RealData2("hello")); //類似Client.request
  System.out.println("執行其它任務");
  Thread.sleep(3000);
  System.out.println("數據的計算結果為:" + data.get());
 }
}

現在回到上文還未解決完的AbstractExecutorService#submit方法。

類比上面的Client#request方法,在Client#request中先創建一個FutureData實例,而在AbstractExecutorService#submit中則是創建一個FutureTask實例,接著Client#request新創建一個線程用于異步執行任務,并直接返回FutureData,而在AbstractExecutorService#submit中同樣也將任務交給了execute方法,并直接返回FutureTask。當然JDK中Future模式的實現更為復雜。

在《ThreadPoolExecutor線程池原理及其execute方法》中我們講解了execute方法,在ThreadPoolExecutor$Worker#runWorker方法第1145行中是對task任務的調用:

//ThreadPoolExecutor$Worker#runWorker
task.run();

submit調用execute以執行run方法,實際執行的是FutureTask中的run方法。在FutureTask#run中,可以看到對任務Callable類型的task異步的執行,以及結果的保存。

以上這篇老生常談java中的Future模式就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持億速云。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

临沂市| 逊克县| 探索| 交口县| 德惠市| 黄大仙区| 平乐县| 奉新县| 宣化县| 上林县| 洛浦县| 南靖县| 尼木县| 阿拉尔市| 建阳市| 兴仁县| 鹿泉市| 濮阳县| 隆昌县| 鄯善县| 镇雄县| 江孜县| 西吉县| 赤水市| 五指山市| 迁西县| 亚东县| 会宁县| 宜君县| 海阳市| 凤城市| 桐乡市| 阿克| 泌阳县| 兰溪市| 岚皋县| 金湖县| 皮山县| 海林市| 独山县| 天峻县|