欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

老生常談java中的Future模式

 更新時(shí)間:2017年06月19日 08:33:48   投稿:jingxian  
下面小編就為大家?guī)硪黄仙U刯ava中的Future模式。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧

jdk1.7.0_79

本文實(shí)際上是對上文《簡單談?wù)凾hreadPoolExecutor線程池之submit方法》的一個(gè)延續(xù)或者一個(gè)補(bǔ)充。在上文中提到的submit方法里出現(xiàn)了FutureTask,這不得不停止腳步將方向轉(zhuǎn)向JavaFuture模式。

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

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

也就是說,Future它代表一個(gè)異步計(jì)算的結(jié)果。

上面就代表了Future模式的執(zhí)行原理,根據(jù)網(wǎng)上的例子,我們可以來自己實(shí)現(xiàn)一個(gè)Future模式。

package com.future;

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

/**
 * 結(jié)果的真實(shí)計(jì)算過程
 * Created by yulinfeng on 6/18/17.
 */
public class RealData implements Data {
 protected String data;

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

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

/**
 * 真實(shí)結(jié)果RealData的代理
 * Created by yulinfeng on 6/18/17.
 */
public class FutureData implements Data {
 RealData realData = null; //對RealData的封裝,代理了RealData
 boolean isReady = false; //真實(shí)結(jié)果是否已經(jīng)準(zhǔn)備好

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

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

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

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

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

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

  return futureData; //先返回一個(gè)“假”的futureData
 }
}
/**
 * 負(fù)責(zé)調(diào)用Client發(fā)起請求,并使用返回的數(shù)據(jù)。
 * 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("準(zhǔn)備計(jì)算結(jié)果");
  Data data = client.request("hello"); //立即返回一個(gè)“假”的futureData,可以不用阻塞的等待數(shù)據(jù)返回,轉(zhuǎn)而執(zhí)行其它任務(wù)
  System.out.println("執(zhí)行其它任務(wù)");
  Thread.sleep(3000);  //模擬執(zhí)行其它任務(wù)
  System.out.println("數(shù)據(jù)的計(jì)算結(jié)果為:" + data.getResult());
 }
}

仔細(xì)閱讀以上程序?qū)uture模式的實(shí)現(xiàn)不難發(fā)現(xiàn),F(xiàn)uture模式是異步請求和代理模式的結(jié)合。當(dāng)然在JDK中已經(jīng)為我們實(shí)現(xiàn)好了Future模式。

修改RealData類:

package com.future;

import java.util.concurrent.Callable;

/**
 * 結(jié)果的真實(shí)計(jì)算過程
 * 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("正在計(jì)算結(jié)果");
   Thread.sleep(2000);  //模擬計(jì)算結(jié)果
  } 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;

/**
 * 負(fù)責(zé)調(diào)用Executor的submit,并使用返回的數(shù)據(jù)。
 * 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("準(zhǔn)備計(jì)算結(jié)果");
  Future<String> data = client.submit(new RealData2("hello")); //類似Client.request
  System.out.println("執(zhí)行其它任務(wù)");
  Thread.sleep(3000);
  System.out.println("數(shù)據(jù)的計(jì)算結(jié)果為:" + data.get());
 }
}

現(xiàn)在回到上文還未解決完的AbstractExecutorService#submit方法。

類比上面的Client#request方法,在Client#request中先創(chuàng)建一個(gè)FutureData實(shí)例,而在AbstractExecutorService#submit中則是創(chuàng)建一個(gè)FutureTask實(shí)例,接著Client#request新創(chuàng)建一個(gè)線程用于異步執(zhí)行任務(wù),并直接返回FutureData,而在AbstractExecutorService#submit中同樣也將任務(wù)交給了execute方法,并直接返回FutureTask。當(dāng)然JDK中Future模式的實(shí)現(xiàn)更為復(fù)雜。

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

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

submit調(diào)用execute以執(zhí)行run方法,實(shí)際執(zhí)行的是FutureTask中的run方法。在FutureTask#run中,可以看到對任務(wù)Callable類型的task異步的執(zhí)行,以及結(jié)果的保存。

以上這篇老生常談java中的Future模式就是小編分享給大家的全部內(nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java面向?qū)ο蟪绦蛟O(shè)計(jì):繼承,多態(tài)用法實(shí)例分析

    Java面向?qū)ο蟪绦蛟O(shè)計(jì):繼承,多態(tài)用法實(shí)例分析

    這篇文章主要介紹了Java面向?qū)ο蟪绦蛟O(shè)計(jì):繼承,多態(tài)用法,結(jié)合實(shí)例形式分析了java繼承與多態(tài)的相關(guān)概念、原理、實(shí)現(xiàn)方法與操作注意事項(xiàng),需要的朋友可以參考下
    2020-04-04
  • Java創(chuàng)建二叉搜索樹,實(shí)現(xiàn)搜索,插入,刪除的操作實(shí)例

    Java創(chuàng)建二叉搜索樹,實(shí)現(xiàn)搜索,插入,刪除的操作實(shí)例

    下面小編就為大家分享一篇Java創(chuàng)建二叉搜索樹,實(shí)現(xiàn)搜索,插入,刪除的操作實(shí)例,具有很好的參考價(jià)值,希望對大家有所幫助
    2017-12-12
  • 快速解決Hash碰撞沖突的方法小結(jié)

    快速解決Hash碰撞沖突的方法小結(jié)

    這篇文章主要介紹了快速解決Hash碰撞沖突的方法小結(jié),具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • RestTemplate實(shí)現(xiàn)發(fā)送帶headers的GET請求

    RestTemplate實(shí)現(xiàn)發(fā)送帶headers的GET請求

    這篇文章主要介紹了RestTemplate實(shí)現(xiàn)發(fā)送帶headers的GET請求,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • SpringMVC存取Session的兩種方法

    SpringMVC存取Session的兩種方法

    Spring MVC是個(gè)非常優(yōu)秀的框架,本篇文章主要介紹了SpringMVC存取Session的兩種方法,具有一定的參考價(jià)值,有興趣的可以了解一下。
    2017-01-01
  • Java中Spring對事務(wù)的支持詳解

    Java中Spring對事務(wù)的支持詳解

    這篇文章主要介紹了Java中Spring對事務(wù)的支持詳解,Spring對事務(wù)的支持有兩種方式,一是自己編寫事務(wù),精確控制事務(wù)的邊界,二是采用聲明事務(wù)的方式,使用AOP來完成,需要的朋友可以參考下
    2023-07-07
  • Spring事務(wù)原理解析

    Spring事務(wù)原理解析

    Spring事務(wù)有可能會(huì)提交,回滾、掛起、恢復(fù),所以Spring事務(wù)提供了一種機(jī)制,可以讓程序員來監(jiān)聽當(dāng)前Spring事務(wù)所處于的狀態(tài),這篇文章主要介紹了Spring底層事務(wù)原理,需要的朋友可以參考下
    2022-12-12
  • Springboot幾種任務(wù)的整合方法

    Springboot幾種任務(wù)的整合方法

    這篇文章主要介紹了Springboot幾種任務(wù)的整合方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-10-10
  • Java接入通義千問的簡單方法示例

    Java接入通義千問的簡單方法示例

    ? 通義千問是阿里云開發(fā)的大語言模型(Large language Model )LLM,旨在提供廣泛的知識和普適性,可以理解和回答各領(lǐng)域中的問題,這篇文章主要給大家介紹了關(guān)于Java接入通義千問的簡單方法,需要的朋友可以參考下
    2024-02-02
  • JAVA實(shí)現(xiàn)空間索引編碼——GeoHash的示例

    JAVA實(shí)現(xiàn)空間索引編碼——GeoHash的示例

    本篇文章主要介紹了JAVA實(shí)現(xiàn)空間索引編碼——GeoHash的示例,如何從眾多的位置信息中查找到離自己最近的位置,有興趣的朋友可以了解一下
    2016-10-10

最新評論