Java使用FutureTask實(shí)現(xiàn)預(yù)加載的示例詳解
FutureTask介紹
FutureTask也可以用作閉鎖;FutureTask的計(jì)算是通過(guò)Callable來(lái)實(shí)現(xiàn)的,相當(dāng)于一種可生成結(jié)果的Runnable,并且可以處于3種狀態(tài),分別是等待運(yùn)行(waiting to run)、正在運(yùn)行(Running)、和運(yùn)行完成(Completed),而運(yùn)行完成表示計(jì)算的所有可能結(jié)束方式,包括正常結(jié)束,由于取消而結(jié)束和由于異常而結(jié)束等,當(dāng)FutureTask進(jìn)入完成狀態(tài)后,它就會(huì)永遠(yuǎn)停止在這個(gè)狀態(tài)上。我們可以使用Future.get()方法獲取任務(wù)執(zhí)行的狀態(tài)。
使用場(chǎng)景
Future.get的行為取決于任務(wù)的狀態(tài),如果任務(wù)已經(jīng)完成,那么get會(huì)立即返回結(jié)果,否則get方法將阻塞直到任務(wù)進(jìn)入完成狀態(tài),然后返回結(jié)果或者拋出異常,F(xiàn)utureTask將計(jì)算結(jié)果從執(zhí)行計(jì)算的線程傳遞到獲取這個(gè)結(jié)果的線程,而FutureTask的規(guī)范確保了這種傳遞過(guò)程能實(shí)現(xiàn)結(jié)果的正確性
基于FutureTask的特性,通??梢允褂肍utureTask做一些預(yù)加載工作,比如一些時(shí)間較長(zhǎng)的計(jì)算,這些計(jì)算可以在使用計(jì)算結(jié)果之前啟動(dòng),并且計(jì)算的結(jié)果將在稍后是同,通過(guò)提前啟動(dòng)計(jì)算,可以減少等待結(jié)果時(shí)需要的時(shí)間
實(shí)例解析
假設(shè)我們要加載一個(gè)產(chǎn)品信息,使用FutureTask來(lái)執(zhí)行一個(gè)高開(kāi)銷(xiāo)的計(jì)算。代碼如下所示: 首先簡(jiǎn)單寫(xiě)一個(gè)產(chǎn)品的Bean類(lèi):
static class ProductInfo {
public ProductInfo(String name, String order_id) {
this.name = name;
this.order_id = order_id;
}
private String name;
private String order_id;
@Override
public String toString() {
return "ProductInfo{" +
"name='" + name + '\'' +
", order_id='" + order_id + '\'' +
'}';
}
}然后使用FutureTask實(shí)現(xiàn)一個(gè)產(chǎn)品信息預(yù)加載功能:
static class Preloader {
public void start() {
thread.start();
}
private final FutureTask<ProductInfo> futureTask =
new FutureTask<>(new Callable<ProductInfo>() {
@Override
public ProductInfo call() throws Exception {
return loadProductInfo();
}
});
public ProductInfo get() throws ExecutionException,
InterruptedException {
return futureTask.get();
}
private final Thread thread = new Thread(futureTask);
private ProductInfo loadProductInfo() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return new ProductInfo("衣服", "9527");
}
}驗(yàn)證代碼:
Preloader preloader = new Preloader();
preloader.start();
System.out.println("start get product info before"
+ System.currentTimeMillis() / 1000);
ProductInfo productInfo = null;
try {
productInfo = preloader.get();
} catch (ExecutionException | InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("start get product info afte"
+System.currentTimeMillis() / 1000);
System.out.println("productInfo: " + productInfo);如上面的代碼所示:Preloader創(chuàng)建了一個(gè)FutureTask,其中包含了加載產(chǎn)品信息的任務(wù),以及一個(gè)執(zhí)行運(yùn)算的線程。我們?cè)黾恿艘粋€(gè) Thread.sleep(5000);模擬加載耗時(shí)。由于在構(gòu)造函數(shù)或者靜態(tài)初始化方法中啟動(dòng)線程不是一種好方法,所以提供了一個(gè)start方法來(lái)啟動(dòng)線程,當(dāng)程序后面需要ProductInfo結(jié)果時(shí),可以調(diào)用Preloader提供的get方法,如果數(shù)據(jù)已經(jīng)加載,那么會(huì)返回這些數(shù)據(jù),否則將等待加載完成后再返回。
到此這篇關(guān)于Java使用FutureTask實(shí)現(xiàn)預(yù)加載的示例詳解的文章就介紹到這了,更多相關(guān)Java FutureTask預(yù)加載內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
RSA加密的方式和解密方式實(shí)現(xiàn)方法(推薦)
下面小編就為大家?guī)?lái)一篇RSA加密的方式和解密方式實(shí)現(xiàn)方法(推薦)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-06-06
Spring使用注解進(jìn)行對(duì)象裝配(DI)的操作
獲取Bean對(duì)象也叫做對(duì)象裝配,就是把對(duì)象取出來(lái)放到某個(gè)類(lèi)中,有時(shí)候也叫對(duì)象注入,這篇文章主要介紹了Spring使用注解進(jìn)行對(duì)象裝配(DI),需要的朋友可以參考下2023-07-07
Spring Data JPA的Audit功能審計(jì)數(shù)據(jù)庫(kù)的變更
數(shù)據(jù)庫(kù)審計(jì)是指當(dāng)數(shù)據(jù)庫(kù)有記錄變更時(shí),可以記錄數(shù)據(jù)庫(kù)的變更時(shí)間和變更人等,這樣以后出問(wèn)題回溯問(wèn)責(zé)也比較方便,本文討論Spring Data JPA審計(jì)數(shù)據(jù)庫(kù)變更問(wèn)題,感興趣的朋友一起看看吧2021-06-06
Spring security實(shí)現(xiàn)對(duì)賬戶進(jìn)行加密
這篇文章主要介紹了Spring security實(shí)現(xiàn)對(duì)賬戶進(jìn)行加密,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03
Java根據(jù)實(shí)體生成SQL數(shù)據(jù)庫(kù)表的示例代碼
這篇文章主要來(lái)和大家分享一個(gè)Java實(shí)現(xiàn)根據(jù)實(shí)體生成SQL數(shù)據(jù)庫(kù)表的代碼,文中的實(shí)現(xiàn)代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-07-07
如何將Object類(lèi)轉(zhuǎn)換為實(shí)體類(lèi)
這篇文章主要介紹了如何將Object類(lèi)轉(zhuǎn)換為實(shí)體類(lèi),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-08-08
Java通過(guò)Lambda函數(shù)的方式獲取屬性名稱
這篇文章主要介紹了通過(guò)Lambda函數(shù)的方式獲取屬性名稱,實(shí)現(xiàn)步驟是通過(guò)定義一個(gè)函數(shù)式接口, 用來(lái)接收l(shuí)ambda方法引用,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2023-10-10
分享Spring Boot 3.x微服務(wù)升級(jí)歷程
Spring Boot 3.0.0 GA版已經(jīng)發(fā)布,好多人也開(kāi)始嘗試升級(jí),有人測(cè)試升級(jí)后,啟動(dòng)速度確實(shí)快了不少,這篇文章主要介紹了Spring Boot 3.x微服務(wù)升級(jí)經(jīng)歷,需要的朋友可以參考下2022-12-12

