日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
異步編程還得看JDK8

什么是異步編程

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

創(chuàng)新互聯(lián)服務(wù)緊隨時代發(fā)展步伐,進(jìn)行技術(shù)革新和技術(shù)進(jìn)步,經(jīng)過10年的發(fā)展和積累,已經(jīng)匯集了一批資深網(wǎng)站策劃師、設(shè)計師、專業(yè)的網(wǎng)站實(shí)施團(tuán)隊以及高素質(zhì)售后服務(wù)人員,并且完全形成了一套成熟的業(yè)務(wù)流程,能夠完全依照客戶要求對網(wǎng)站進(jìn)行網(wǎng)站設(shè)計、成都網(wǎng)站建設(shè)、建設(shè)、維護(hù)、更新和改版,實(shí)現(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ù)做其他事情,等到需要的時候再向工作線程獲取結(jié)果。

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

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

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

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

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

我們來寫案例代碼實(shí)驗(yà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) {

}
}

運(yùn)行結(jié)果:

第一步: 網(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í)行的結(jié)果
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í)行結(jié)果:

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

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

CompletableFuture

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

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

之前 Future 需要等待 isDone 為 true 才能知道任務(wù)跑完了?;蛘呔褪怯?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不同在與前者異步返回一個結(jié)果,后者是void.第二個函數(shù)第二個參數(shù)表示是用我們自己創(chuàng)建的線程池,否則采用默認(rèn)的ForkJoinPool.commonPool()作為它的線程池.其中Supplier是一個函數(shù)式接口,代表是一個生成者的意思,傳入0個參數(shù),返回一個結(jié)果。

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

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

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

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


分享文章:異步編程還得看JDK8
本文路徑:http://www.5511xx.com/article/dpijohh.html