Java多執行緒程式設計模式實戰指南之Promise模式

2021-09-17 03:46:56 字數 4094 閱讀 8885

本書其它部分內容也在本站發表過,詳見:\\

promise模式簡介

\\ promise模式是一種非同步程式設計模式 。它使得我們可以先開始乙個任務的執行,並得到乙個用於獲取該任務執行結果的憑據物件,而不必等待該任務執行完畢就可以繼續執行其他操作。等到我們需要該任務的執行結果時,再呼叫憑據物件的相關方法來獲取。這樣就避免了不必要的等待,增加了系統的併發性。這好比我們去小吃店,同時點了鴨血粉絲湯和生煎包。當我們點餐付完款後,我們拿到手的其實只是一張可藉以換取相應食品的收銀小票(憑據物件)而已,而不是對應的實物。由於鴨血粉絲湯可以較快製作好,故我們可以憑收銀小票即刻兌換到。而生煎包的製作則比較耗時,因此我們可以先吃拿到手的鴨血粉絲湯,而不必餓著肚子等生煎包出爐再一起吃。等到我們把鴨血粉絲湯吃得差不多的時候,生煎包可能也出爐了,這時我們再憑收銀小票去換取生煎包,如圖6-1所示。

\\ 圖6-1.promise模式的日常生活例子

\\promise模式的架構

\\ promise模式中,客戶端**呼叫某個非同步方法所得到的返回值僅是乙個憑據物件(該物件被稱為promise,意為「承諾」)。憑藉該物件,客戶端**可以獲取非同步方法相應的真正任務的執行結果。為了討論方便,下文我們稱非同步方法對應的真正的任務為非同步任務。

\\ promise模式的主要參與者有以下幾種。其類圖如圖6-2所示。

\\ 圖6-2.promise模式的類圖

\\ \\t

​​promise:包裝非同步任務處理結果的憑據物件。負責檢測非同步任務是否處理完畢、返回和儲存非同步任務處理結果。其主要方法及職責如下。\\t

\\tresult:負責表示非同步任務處理結果。具體型別由應用決定。\\t

taskexecutor:負責真正執行非同步任務所代表的計算,並將其計算結果設定到相應的promise例項。其主要方法及職責如下\\t

\客戶端**獲取非同步任務處理結果的過程如圖6-3所示的序列圖。

\\ 圖6-3.獲取非同步任務的處理結果

\\ 第1步:客戶端**呼叫promisor的非同步方法compute。

\\ 第2、3步:compute方法建立promise例項作為該方法的返回值,並返回。

\\ 第4步:客戶端**呼叫其所得到的promise物件的getresult方法來獲取非同步任務處理結果。如果此時非同步任務執行尚未完成,則getresult方法會阻塞(即呼叫方**的執行執行緒暫時處於阻塞狀態)。

\\ 非同步任務的真正執行以及其處理結果的設定如圖6-4所示的序列圖。

\\ 圖6-4.設定非同步任務的處理結果

\\ 第1步:promisor的非同步方法compute建立taskexecutor例項。

\\ 第2步:taskexecutor的run方法被執行(可以由專門的執行緒或者執行緒池 來呼叫run方法)。

\\ 第3步:run方法建立表示其執行結果的result例項。

\\ 第4、5步:run方法將其處理結果設定到相應的promise例項上。

\\promise模式實戰案例解析

\\ 某系統的乙個資料同步模組需要將一批本地檔案上傳到指定的目標ftp伺服器上。這些檔案是根據頁面中的輸入條件查詢資料庫的相應記錄生成的。在將檔案上傳到目標伺服器之前,需要對ftp客戶端例項進行初始化(包括與對端伺服器建立網路連線、向伺服器傳送登入使用者和向伺服器傳送登入密碼)。而ftp客戶端例項初始化這個操作比較耗時間,我們希望它盡可能地在本地檔案上傳之前準備就緒。因此我們可以引入非同步程式設計,使得ftp客戶端例項初始化和本地檔案上傳這兩個任務能夠併發執行,減少不必要的等待。另一方面,我們不希望這種非同步程式設計增加了**編寫的複雜性。這時,promise模式就可以派上用場了:先開始ftp客戶端例項的初始化,並得到乙個獲取ftp客戶端例項的憑據物件。在不必等待ftp客戶端例項初始化完畢的情況下,每生成乙個本地檔案,就通過憑據物件獲取ftp客戶端例項,再通過該ftp客戶端例項將檔案上傳到目標伺服器上。**如清單6-1所示 。

\\ 清單6-1.資料同步模組的入口類

\\

\public class datasynctask implements runnable \\t@override\\tpublic void run()  catch (interruptedexception e)  catch (executionexception e) \\t\t// 上傳檔案\\t\tuploadfiles(ftpclientutil);\\t\t//省略其他**\\t}\\tprivate void generatefilesfromdb() \\tprivate void uploadfiles(ftpclientutil ftpclientutil)  catch (exception e) \\t\t}\\t}\\tprivate set\u0026lt;file\u0026gt; retrievegeneratedfiles() \}\
\\

從清單6-1的**中可以看出,datasynctask類的run方法先開始ftp客戶端例項的初始化,並得到獲取相應ftp客戶端例項的憑據物件ftpclientutilpromise。接著,它直接開始查詢資料庫並生成本地檔案。而此時,ftp客戶端例項的初始化可能尚未完成。在本地檔案生成之後,run方法通過呼叫ftpclientutilpromise的get方法來獲取相應的ftp客戶端例項。此時,如果相應的ftp客戶端例項的初始化仍未完成,則該呼叫會阻塞,直到相應的ftp客戶端例項的初始化完成或者失敗。run方法獲取到ftp客戶端例項後,呼叫其upload方法將檔案上傳到指定的ftp伺服器。

\\ 清單6-1**所引用的ftp客戶端工具類ftpclientutil的**如清單6-2所示。

\\ 清單6-2.ftp客戶端工具類原始碼

\\

\//模式角色:promise.promisor、promise.result\public class ftpclientutil \\\t//模式角色:promise.promisor.compute\\tpublic static future\u0026lt;ftpclientutil\u0026gt; newinstance(final string ftpserver,\\t    final string username, final string password) \\\t\t};\\\t\t//task相當於模式角色:promise.promise\\t\tfinal futuretask\u0026lt;ftpclientutil\u0026gt; task = new futuretask\u0026lt;ftpclientutil\u0026gt;(\\t\t    callable);\\\t\t/*\\t\t下面這行**與本案例的實際**並不一致,這是為了討論方便。\\t\t下面新建的執行緒相當於模式角色:promise.taskexecutor\\t\t*/\\t\tnew thread(task).start();\\t\treturn task;\\t}\\\tprivate void init(string ftpserver, string username, string password)\\t    throws exception \\t\tboolean isok = ftp.login(username, password);\\t\tif (isok)  else \\\t\treply = ftp.cwd(\"~/subspsync\");\\t\tif (!ftpreply.ispositivecompletion(reply))  else \\\t\tftp.setfiletype(ftp.ascii_file_type);\\\t}\\\tpublic void upload(file file) throws exception \\\t\t\ttry  catch (ioexception e) \\t\t\tif (isok) {\\t\t\t\tftp.storefile(filename + \".c\

Java多執行緒程式設計模式實戰指南之Promise模式

本書其它部分內容也在本站發表過,詳見 promise模式簡介 promise模式是一種非同步程式設計模式 它使得我們可以先開始乙個任務的執行,並得到乙個用於獲取該任務執行結果的憑據物件,而不必等待該任務執行完畢就可以繼續執行其他操作。等到我們需要該任務的執行結果時,再呼叫憑據物件的相關方法來獲取。這...

Java多執行緒程式設計模式實戰指南之Promise模式

本書其它部分內容也在本站發表過,詳見 promise模式簡介 promise模式是一種非同步程式設計模式 它使得我們可以先開始乙個任務的執行,並得到乙個用於獲取該任務執行結果的憑據物件,而不必等待該任務執行完畢就可以繼續執行其他操作。等到我們需要該任務的執行結果時,再呼叫憑據物件的相關方法來獲取。這...

多執行緒程式設計指南

老狼推薦 多執行緒程式設計指南 最後希望這篇文件能幫上那些感覺看官方英文文件困難的人。如果可以我還是推薦盡量檢視英文原文件,畢竟那是原汁原味,翻譯總無法避免有一定的疏漏。下期預告 core data 程式設計指南 以下提供目錄預覽 目錄推薦資源 核心動畫程式設計指南 core animation p...