java中的Future的設計模式 手寫一個簡易的Future

案例

例如:今天是小妹的生日,需要一個蛋糕有點儀式感,于是去蛋糕店預定,預定完之后,店老板說蛋糕做好了,到時電話通知你,不可能在這傻傻的等著吧,還有其他事情要做啊,于是我的去做其他事情,等老板電話后再來取蛋糕。這樣可以充分利用自己的時間去賺錢,如果用這個案例寫一個Java代碼 如何實現,

Future的理解和用途

Future是個未來的事情,相當與一個票據,或者可以理解是一個憑證,用這個憑證去獲取所需要的結果,

代碼的邏輯解析

SimpleFuture —>代表未來的一個憑據
SimpleFutureTask —>將你的調用邏輯進行隔離封裝
SimpleFutureService —> 橋接Future和FutureTask
這是一種很好的設計模式 SimpleFuture 不需要知道 SimpleFutureTask的存在,而SimpleFutureTask也不需要知道SimpleFuture 的存在,只要SimpleFutureService 需要知道他們兩者的存在,而對于調用者而言,只要知道SimpleFutureService 就行,我們將業務邏輯封裝成一個task模式,并且返回一個SimpleFuture

簡單的Future憑證接口

1、get方法
獲取任務結束后返回的結果,如果調用時,任務還沒有結束,則會進行阻塞線程,直到任務完成。該阻塞是可以被打斷的,打斷的線程是調用get方法的線程,被打斷后原任務會依舊繼續執行。

/*** SimpleFuture接口定義了一個簡單的異步計算的結果獲取方法* 它提供了一種機制來獲取異步任務的結果,如果任務尚未完成,則調用get方法的線程會被阻塞,* 直到計算完成并且結果可用* * @param <T> 表示異步計算結果的類型*/
public interface SimpleFuture<T> {/*** 獲取異步計算的結果如果計算尚未完成,則此方法會阻塞,直到計算完成* 如果計算過程中遇到中斷,此方法會拋出InterruptedException* * @return 異步計算的結果* @throws InterruptedException 如果調用get方法的線程在等待計算完成時被中斷*/T get() throws InterruptedException;
}

獲取任務的結果

/*** SimpleFutureTask接口定義了一個異步任務的標準.* 它代表了一個將會在將來執行的任務,并且該任務有一個結果.* 這個接口的主要用途是為那些想要實現異步執行并返回結果的任務提供一個統一的標準.** @param <T> 表示任務返回結果的類型.*/
public interface SimpleFutureTask<T> {/*** 執行異步任務并返回結果.* 該方法將在某個時刻被調用,以期望異步地完成任務并返回結果.* * @return 任務的結果,類型為泛型T.*/T call();
}

實現SimpleFuture的接口

/*** AsynSimpleFuture 類實現了一個異步操作的簡單未來對象* 它允許在一個線程中設置結果,在另一個線程中獲取結果* 主要用于線程間通信,以異步方式處理任務的結果** @param <T> 未來操作結果的類型*/
public class AsynSimpleFuture<T> implements SimpleFuture<T>{// 標記任務是否完成,volatile 關鍵字確保多線程環境下的可見性private volatile boolean finished = false;// 存儲任務的結果private T result;/*** 當任務完成時調用此方法,它會設置結果值并通知所有等待的線程** @param result 任務的結果*/public void finish(T result){synchronized (this){this.result = result;this.finished = true;this.notifyAll();}}/*** 獲取任務的結果如果任務未完成,當前線程會等待直到任務完成** @return 任務的結果* @throws InterruptedException 如果在等待過程中線程被中斷*/@Overridepublic T get() throws InterruptedException {synchronized (this){while (!finished){this.wait();}}return result;}
}

將SimpleFutureTask和 SimpleFutureTask 或 AsynSimpleFuture聯系起來

/*** SimpleFutureService類提供了異步執行任務的功能* 它通過管理線程來執行提交的任務,并返回一個表示異步計算結果的AsynSimpleFuture對象*/
public class SimpleFutureService {/*** 提交一個SimpleFutureTask任務進行異步執行* 該方法的返回值可以為 SimpleFuture<T>* @param task 要異步執行的任務,它實現了call方法來定義任務的具體執行邏輯* @return 返回一個AsynSimpleFuture對象,通過它可以獲取任務執行結果* * 此方法創建并啟動一個新的線程來執行給定的任務任務的執行結果會被封裝在這個AsynSimpleFuture對象中* 使用者可以使用這個對象來獲取任務執行結果,而無需阻塞當前線程*/public <T> AsynSimpleFuture<T> submit(SimpleFutureTask<T> task, Consumer<T> consumer) {AsynSimpleFuture<T> future = new AsynSimpleFuture<>();new Thread(() -> {T result = task.call();future.finish(result);consumer.accept(result);}).start();return future;}
}

測試一下代碼的效果

/*** SyncInvoker 類用于演示如何使用 SimpleFutureService 來執行異步任務并在任務完成后獲取結果*/
public class SyncInvoker {/*** 主函數執行異步任務并展示執行結果* @param args 命令行參數* @throws InterruptedException 如果在睡眠期間線程被中斷*/public static void main(String[] args) throws InterruptedException {// 創建 SimpleFutureService 實例SimpleFutureService simpleFutureService = new SimpleFutureService();// 提交異步任務并獲取未來結果simpleFutureService.submit(SyncInvoker::bookAndPickUpCake,System.out::println);Optional.of("-----*************-------").ifPresent(System.out::println);// 應該是在獲取結果之前,先執行其他任務Optional.of("-----go to work-------").ifPresent(System.out::println);// 模擬其他任務的耗時Thread.sleep(5000);Optional.of("-----I finish my work -------").ifPresent(System.out::println);Optional.of("-----####去蛋糕店等待或等待老板電話或老板送貨上面#####-------").ifPresent(System.out::println);}/*** 模擬一個耗時的異步任務,例如預訂并取回蛋糕* @return 任務結果,在這個例子中是蛋糕的名稱*/private static String bookAndPickUpCake() {try {// 模擬耗時操作Thread.sleep(10000);return "BIRTHDAY CAKE";} catch (InterruptedException e) {throw new RuntimeException(e);}}
}執行的結果:
-----*************-------
-----go to work-------
-----I finish my work -------
-----####等待老板電話或老板送貨上面#####-------
BIRTHDAY CAKE

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/79159.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/79159.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/79159.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【Redis】Redis C++使用

一、Redis的自定義網絡協議 1.1 為什么可以編寫出一個自定義的Redis客戶端 為什么我們可以編寫出一個自定義的Redis客戶端&#xff1f;因為Redis公開了自己的自定義協議。而對于一些其他軟件的客戶端&#xff0c;我們無法編寫出一個自定義的Redis客戶端&#xff0c;因為他們沒…

【軟考系統架構設計師】軟件工程知識點

1、 軟件開發生命周期 軟件定義時期&#xff1a;包括可行性研究和詳細需求分析過程&#xff0c;任務是確定軟件開發工程必須完成的總目標&#xff0c;具體分為問題定義、可行性研究、需求分析等 軟件開發時期&#xff1a;軟件的設計與實現&#xff0c;分為概要設計、詳細設計、…

DeepSeek 與開源:肥沃土壤孕育 AI 碩果

當國產 AI DeepSeek 以其低成本推理和多模態能力在全球范圍內引起轟動時&#xff0c;人們驚嘆于中國技術的迅猛發展&#xff0c;卻很少有人深究這一成就背后的根基。答案其實早已寫在中國開源生態二十多年的發展歷程中。 從倪光南院士提出“以開源打破技術壟斷”的理念&#x…

職坐標:智慧城市未來發展的核心驅動力

內容概要 智慧城市的演進正以顛覆性創新重構人類生存空間&#xff0c;其發展脈絡由物聯網、人工智能與云計算三大技術支柱交織而成。這些技術不僅推動城市治理從經驗決策轉向數據驅動模式&#xff0c;更通過實時感知與智能分析&#xff0c;實現交通、能源等領域的精準調控。以…

vue復習46~90

1.小兔鮮 所有都折疊 ctrl k,ctrl0 所有都展開 ctrl k,ctrlj當前結構渲染5次 <BaseBrandItem v-for"item in 5" :key"item"><BaseBrandItem>2.scoped樣式沖突 結構&#xff1a;只能有一個根元素樣式&#xff1a;全局樣式(默認)&#xff1…

PHP 用 workman 即時通訊,做個簡版QQ

1. workman是什么 &#xff0c;一般應用在那些地方 workerman是一個高性能的PHP socket 服務器框架&#xff0c;workerman基于PHP多進程以及libevent事件輪詢庫&#xff0c;PHP開發者只要實現一兩個接口&#xff0c;便可以開發出自己的網絡應用&#xff0c;例如Rpc服務、聊天室…

【WORD】批量將doc轉為docx

具體步驟進行&#xff1a; 打開Word文檔&#xff0c;按下AltF11快捷鍵&#xff0c;打開VBA編輯器。在VBA編輯器中&#xff0c;左側的“項目資源管理器”窗口會顯示當前打開的Word文檔相關項目。找到您要添加代碼的文檔項目&#xff08;通常以文檔名稱命名&#xff09;&#xf…

【免費】【實測有用】5KPlayer Windows 電腦作為 MacBook 無線擴展屏

總結&#xff1a;使用 5KPlayer 將 Windows 電腦作為 MacBook 無線擴展屏 準備工作 設備要求&#xff1a; MacBook 和 Windows 電腦需連接到同一 Wi-Fi 網絡。【這里有雷&#xff1a;eduroam不會成功&#xff0c;家里的WIFI成功了&#xff0c;需要確認校園網是否可行。】確保…

華為華三模擬器解決兼容問題Win11 24H2 現在使用ENSP的問題解決了

一、Win11 24H2 現在使用ENSP的問題解決了 這個Win11 的 24H2不能使用ENSP的問題已經困擾我們很久了,在之前的文章中,我們也有說明這個問題 之前ENSP肯定啟動會報錯40 當時還建議大家先不要更新到win11的24H2版本,現在終于迎來了更新,不用再擔心了,包括早就升級了24H2版…

嵌入式WebRTC輕量化SDK壓縮至500K-800K ,為嵌入式設備節省Flash資源

一、SDK輕量化的核心技術實現 1、WebRTC庫裁剪與模塊化設計 EasyRTC針對嵌入式設備的資源限制&#xff0c;對原生WebRTC庫進行深度裁剪&#xff0c;僅保留核心通信功能&#xff08;如信令管理、編解碼、網絡傳輸等&#xff09;&#xff0c;移除冗余組件&#xff08;如部分調試…

Maya云渲染工作流,提升渲染速度

在三維動畫與影視特效領域&#xff0c;Autodesk Maya作為行業標桿工具&#xff0c;承載著從角色建模到復雜特效渲染的全流程創作。然而&#xff0c;本地硬件性能不足、渲染周期漫長、跨團隊協作效率低等痛點始終困擾著創作者。渲染101云渲染以彈性算力資源、智能化工作流與全方…

git怎么使遠程分支回退到指定的節點處

git使遠程分支回退到指定的節點 引言場景描述步驟 引言 最近提交代碼的時候&#xff0c;總將分支合并錯&#xff0c;原本要合到A分支&#xff0c;結果合并到了B分支&#xff0c;這樣就導致b分支需要回退到我沒有合并之前的節點處。 本文記錄下怎么將遠程分支回退到指定的節點。…

全網通emotn ui桌面免費嗎?如何開機自啟動

在智能設備的使用中&#xff0c;一款優秀的桌面系統能帶來截然不同的體驗。全網通Emotn UI桌面便是其中的佼佼者&#xff0c;它以完全免費的特性與卓越性能&#xff0c;成為眾多用戶的心頭好。 其簡潔美觀的界面設計如同為設備換上"清新外衣"&#xff0c;常用功能一…

通過微信APPID獲取小程序名稱

進入微信公眾平臺&#xff0c;登錄自己的小程序后臺管理端&#xff0c;在“賬號設置”中找到“第三方設置” 在“第三方設置”頁面中&#xff0c;將頁面拉到最下面&#xff0c;即可通過appid獲取到這個小程序的名稱信息

2025年第十六屆藍橋杯省賽JavaB組真題回顧

第16屆藍橋杯省賽已經結束了&#xff0c;第一次參加也是坐牢了4個小時&#xff0c;現在還是來總結一下吧&#xff08;先聲明以下的解法&#xff0c;大家可以當作一種思路來看&#xff0c;解法不一定是正解&#xff0c;只是給大家提供一種能夠正常想到的思路吧&#xff09; 試題…

深入剖析 Axios 的 POST 請求:何時使用 qs 處理數據

在前端開發中&#xff0c;Axios 是一個廣泛使用的用于發送 HTTP 請求的庫&#xff0c;特別是在處理 POST 請求時&#xff0c;數據的處理方式會直接影響到請求能否正確被后端接收和處理。其中&#xff0c;使用 qs 庫對數據進行處理是一個常見的操作點&#xff0c;本文將深入探討…

通過websocket給服務端發送訂單催單提醒消息

controller層 GetMapping("/reminder/{id}")public Result Remainder(PathVariable("id") Long id){orderService.remainder(id);return Result.success();} 實現類 Overridepublic void remainder(Long id) {Orders ordersDB orderMapper.getById(id);…

ros_note02

note02 節點 ROS2中每一個節點只負責一個單獨的模塊化功能 如&#xff1a;一個節點負責控制車輪轉動&#xff0c;一個節點負責從激光雷達獲取數據&#xff0c;一個節點負責定位 通信方式&#xff1a; 話題&#xff1a;topic服務&#xff1a;services動作&#xff1a;Actio…

使用治療前MR圖像預測腦膜瘤Ki-67的多模態深度學習模型

大家好&#xff0c;我是帶我去滑雪&#xff01; 腦膜瘤是一種常見的腦部腫瘤&#xff0c;Ki-67作為腫瘤細胞增殖的標志物&#xff0c;對于評估腫瘤的生物學行為、預后以及治療方案的制定具有至關重要的作用。然而&#xff0c;傳統的Ki-67檢測依賴于組織學切片和免疫組化染色等方…

【大模型系列篇】深度研究智能體技術演進:從DeepResearch到DeepResearcher,如何重構AI研究范式

DeepResearch 的概念與功能最早由 Google 在 Gemini 系列產品中推出&#xff0c;用于自動化生成結構化研究報告&#xff0c;近期底層依賴模型Gemini升級到了2.5 Pro。而我們常規認知的DeepResearch是由OpenAI推出的一款由優化版的 o3 模型驅動專注于深度研究和分析的AI智能體產…