av激情亚洲男人的天堂国语,日韩欧美精品一中文字幕,无码av一区二区三区无码,国产又色又爽又刺激的a片,国产又色又爽又刺激的a片

異步編程還得看JDK8

什么是異步編程

在很多時候,我們在進程中使用單一線程從頭到尾地執(zhí)行程序,比如程序向另外一臺服務器發(fā)出請求,由于網(wǎng)絡等外部原因,此種通信任務往往會耗費大量時間,進程如果在此期間僅僅只能等待網(wǎng)絡或網(wǎng)絡上其他機器的響應,將嚴重地降低了性能。

創(chuàng)新互聯(lián)服務緊隨時代發(fā)展步伐,進行技術革新和技術進步,經(jīng)過10年的發(fā)展和積累,已經(jīng)匯集了一批資深網(wǎng)站策劃師、設計師、專業(yè)的網(wǎng)站實施團隊以及高素質(zhì)售后服務人員,并且完全形成了一套成熟的業(yè)務流程,能夠完全依照客戶要求對網(wǎng)站進行網(wǎng)站設計、成都網(wǎng)站建設、建設、維護、更新和改版,實現(xiàn)客戶網(wǎng)站對外宣傳展示的首要目的,并為客戶企業(yè)品牌互聯(lián)網(wǎng)化提供全面的解決方案。

如果程序調(diào)用某個方法,等待其執(zhí)行全部處理后才能繼續(xù)執(zhí)行,我們稱其為同步的。相反,在處理完成之前就返回調(diào)用方法則是異步的。

我們在編程語言的流程中添加了異步控制的部分,這部分的編程可以稱之為異步編程。

JDK中的異步編程

Future

Future模式在 JDK5 的時候就有, Future模式,只是發(fā)起了耗時操作,函數(shù)立馬就返回了,真正執(zhí)行具體操作由另外一個工作線程去完成,并不會阻塞客戶端線程。所以在工作線程執(zhí)行耗時操作的時候客戶端無需等待,可以繼續(xù)做其他事情,等到需要的時候再向工作線程獲取結果。

舉個最簡單的例子,我們燒水的時候么,不用一直在爐子旁邊看著,在燒水的過程中,我們需要做一些其他的事情,比如去寫一會代碼,但是在你去寫代碼之前,會給你一個假的結果,比如,我已經(jīng)燒開了,但是,在你去寫代碼的時候,他就開始瘋狂加火,等到水燒開為止,等到你口渴想倒水的時候,發(fā)現(xiàn)水是已經(jīng)燒開的,也就是說,當你在寫代碼之前的時候收到的是個假的結果。

實際上,F(xiàn)uture 模式無法立即給出你想要的結果,但它會給你一個契約,之后你可以隨時通過這個契約來獲取你想要的結果。

異步模式主要是和同步模式進行對比的,我們畫個圖來看看。

黃色區(qū)域的位置的Y軸長度則表示的是你需要等待的所有時間,在這個時間內(nèi),你沒有辦法做任何的事情,只能在這里等著,但是異步的話,就完全不用這個樣子了。

在JDK中Future模式有一套完整的實現(xiàn)。

我們來寫案例代碼實驗一下:

沒有是用 Future 的代碼。

NormalThreadTest

public class NormalThreadTest {

public static void main(String[] args) throws Exception {
long start = System.currentTimeMillis();
// 開啟購買廚具線程
ShoppingThread shopping = new ShoppingThread();
shopping.start();
shopping.join(); // 保障廚具購買并送貨
// 獲取到購買廚具
KitchenWare kc = shopping.kc;

// 買食材
FoodMaterial fm = new FoodMaterial();
Thread.sleep(2000);
System.out.println("第二步: 食材已經(jīng)到位");
// 烹飪美食
cooking(kc, fm);
System.out.println("第三步: 美食烹飪完成");
long end = System.currentTimeMillis();
System.out.println("烹飪美食時間為:" + (end - start));
}


/**
* 定義網(wǎng)上購物廚具線程
* @author Administrator
*
*/
static class ShoppingThread extends Thread {

// 廚具對象引用
private KitchenWare kc;

@Override
public void run() {
System.out.println("第一步: 網(wǎng)上下單");
System.out.println("第一步: 等待廚具");
try {
Thread.sleep(5000); // 等待廚具時間
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("第一步: 快遞送貨");
// 生產(chǎn)廚具
kc = new KitchenWare();
}
}

/**
* 廚具類
* @author Administrator
*
*/
static class KitchenWare {

}

/**
* 食材類
* @author Administrator
*
*/
static class FoodMaterial {

}

/**
* 定義烹飪食物的方法
* @param kc
* @param fm
*/
static void cooking(KitchenWare kc, FoodMaterial fm) {

}
}

運行結果:

第一步: 網(wǎng)上下單
第一步: 等待廚具
第一步: 快遞送貨
第二步: 食材已經(jīng)到位
第三步: 美食烹飪完成
烹飪美食時間為:7043

已經(jīng)使用Future的代碼。

FutureThreadTest

public class FutureThreadTest {


public static void main(String[] args) throws Exception {
long start = System.currentTimeMillis();

Callable callable = new Callable() {
public KitchenWare call() throws Exception {
System.out.println("第一步: 網(wǎng)上下單");
System.out.println("第一步: 等待廚具");
try {
Thread.sleep(5000); // 等待廚具時間
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("第一步: 快遞送貨");
return new KitchenWare();
}

};
// 包裝為異步執(zhí)行的對象
FutureTask task = new FutureTask<>(callable);
new Thread(task).start();

// 買食材
FoodMaterial fm = new FoodMaterial();
Thread.sleep(2000);
System.out.println("第二步: 食材已經(jīng)到位");

if (!task.isDone()) {
System.out.println("廚具還沒有到.....");
}
// 通過阻塞形式獲取到異步塊執(zhí)行的結果
KitchenWare kc = task.get(); // 阻塞
// 烹飪美食
cooking(kc, fm);
System.out.println("第三步: 美食烹飪完成");
long end = System.currentTimeMillis();
System.out.println("烹飪美食時間為:" + (end - start));
}


/**
* 廚具類
* @author Administrator
*
*/
static class KitchenWare {

}

/**
* 食材類
* @author Administrator
*
*/
static class FoodMaterial {

}

/**
* 定義烹飪食物的方法
* @param kc
* @param fm
*/
static void cooking(KitchenWare kc, FoodMaterial fm) {

}
}

執(zhí)行結果:

第一步: 網(wǎng)上下單
第一步: 等待廚具
第二步: 食材已經(jīng)到位
廚具還沒有到.....
第一步: 快遞送貨
第三步: 美食烹飪完成
烹飪美食時間為:5027

這個是JDK5中就有的 Future 來實現(xiàn) 異步編程的,那么接下來我們看1.8的異步編程。

CompletableFuture

Future 雖然可以實現(xiàn)獲取異步執(zhí)行結果的需求,但是它沒有提供通知的機制,我們無法得知Future什么時候完成,我們通過上面的代碼也完全能看出來。

為什么在JDK5之后,又推出新的異步編程,因為使用 Future 要么使用阻塞,在 future.get() 的地方等待 Future 返回的結果,這時又變成同步操作。要么使用 isDone() 輪詢地判斷 Future 是否完成,這樣會耗費CPU的資源。所以阿粉猜測所以在JDK8又推出了 CompletableFuture。

之前 Future 需要等待 isDone 為 true 才能知道任務跑完了?;蛘呔褪怯?get 方法調(diào)用的時候會出現(xiàn)阻塞。而使用 CompletableFuture 的使用就可以用 then , when 等等操作來防止以上的阻塞和輪詢 isDone 的現(xiàn)象出現(xiàn)。

CompletableFuture 有四個方法來創(chuàng)建CompletableFuture對象。

public static CompletableFuture   runAsync(Runnable runnable)

public static CompletableFuture runAsync(Runnable runnable, Executor executor)

public static CompletableFuture supplyAsync(Supplier supplier)

public static CompletableFuture supplyAsync(Supplier supplier, Executor executor)

Asynsc表示異步,而supplyAsync與runAsync不同在與前者異步返回一個結果,后者是void.第二個函數(shù)第二個參數(shù)表示是用我們自己創(chuàng)建的線程池,否則采用默認的ForkJoinPool.commonPool()作為它的線程池.其中Supplier是一個函數(shù)式接口,代表是一個生成者的意思,傳入0個參數(shù),返回一個結果。

我們寫一個最簡單的測試代碼:

public static void test2() throws Exception {
//supplyAsync內(nèi)部使用ForkJoinPool線程池執(zhí)行任務
CompletableFuture completableFuture=CompletableFuture.supplyAsync(()->{
//模擬執(zhí)行耗時任務
System.out.println("task doing...");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//返回結果
return "100";
}).whenComplete((v,r)->{
System.out.println("計算結果是: "+v);
});
//CompletableFuture里使用的線程池里的線程默認是daemon的。main線程結束后,整個程序也
//結束了,這里將main線程join后任務里的代碼才可以執(zhí)行完
Thread.currentThread().join();
}

而使用 CompletableFuture 能有效的避開使用 Futrue 出現(xiàn)的缺點。

看來,JDK 每一次的更新?lián)Q代,不光是加了一些新的內(nèi)容,而且像開發(fā)一樣,每次迭代的時候,同時也會更新之前的一些不完美的內(nèi)容,不是么?


標題名稱:異步編程還得看JDK8
文章網(wǎng)址:http://uogjgqi.cn/article/dpijohh.html
掃二維碼與項目經(jīng)理溝通

我們在微信上24小時期待你的聲音

解答本文疑問/技術咨詢/運營咨詢/技術建議/互聯(lián)網(wǎng)交流