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

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

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
Java多線程并發(fā)編程,一定要巧用Future!

代碼是如何被運(yùn)行的?

那我們先來(lái)看看這個(gè)所謂的多線程并發(fā)編程到底是怎么個(gè)運(yùn)行原理呢?

其實(shí)這個(gè)問(wèn)題,我們必須得從 main 方法開(kāi)始說(shuō)起,簡(jiǎn)單來(lái)說(shuō),你寫(xiě)一段 Java 代碼,其實(shí)一般來(lái)說(shuō)啟動(dòng)和執(zhí)行這些 Java 代碼,都必須去運(yùn)行一個(gè) main 方法對(duì)不對(duì),而且現(xiàn)在比較流行這個(gè) SpringBoot,其實(shí) SpringBoot 也是基于 main 方法來(lái)啟動(dòng)的。

那運(yùn)行代碼的時(shí)候首先會(huì)干什么呢?其實(shí)首先他會(huì)啟動(dòng)一個(gè) JVM 進(jìn)程,接著 JVM 會(huì)去加載你寫(xiě)的類(lèi),然后開(kāi)始運(yùn)行你的 main 方法的代碼,進(jìn)而運(yùn)行你寫(xiě)的所有其他代碼。

在運(yùn)行代碼的過(guò)程中,他需要什么類(lèi)就把那個(gè)類(lèi)從磁盤(pán)上的代碼文件里加載到內(nèi)存里就行了。

如下圖:

那么這個(gè)時(shí)候我提一個(gè)問(wèn)題,大家思考一下,那就是 JVM 進(jìn)程他是怎么運(yùn)行 main 方法的呢?是 JVM 進(jìn)程自己直接去執(zhí)行 main 方法里面的代碼嗎?

當(dāng)然不是了,其實(shí)所有代碼運(yùn)行都得靠線程,一個(gè)進(jìn)程里是可以開(kāi)很多線程的,所以 JVM 進(jìn)程是會(huì)有一個(gè)默認(rèn)的線程,叫做 main 線程,這個(gè) main 線程就負(fù)責(zé)運(yùn)行我們的 main 方法的代碼了。

如下圖:

多線程編程是什么?

那么這個(gè)時(shí)候所謂的多線程編程是什么意思呢?更簡(jiǎn)單了,如果你要是不開(kāi)多線程,默認(rèn)情況下,就是 main 線程一個(gè)線程運(yùn)行你的 main 方法以及后續(xù)的所有代碼。

此時(shí)如果你要是想要開(kāi)啟更多的線程同時(shí)運(yùn)行別的代碼,可以用 new Thread().start() 這種代碼,直接開(kāi)啟一個(gè)線程,那個(gè)線程就會(huì)同時(shí)并發(fā)的運(yùn)行,運(yùn)行他那部分代碼了。

注意,多線程是可以并發(fā)運(yùn)行的,也就是說(shuō) main 線程和新開(kāi)的 Thread 線程幾乎是同時(shí)并發(fā)運(yùn)行的。

如下圖:

那么這個(gè)時(shí)候問(wèn)題來(lái)了,對(duì)于你的 main 線程來(lái)說(shuō),開(kāi)了一個(gè) thread 線程去執(zhí)行部分代碼。

可是問(wèn)題是,你是希望等到這個(gè) thread 線程運(yùn)行結(jié)束以后給你一個(gè)返回值的,可是你又不知道這個(gè) thread 線程什么時(shí)候運(yùn)行完畢,你更不知道這個(gè) thread 線程如何把他的返回值交給你。

也就是說(shuō),你這個(gè) main 線程和 thread 線程之間缺少了一些控制的途徑。

如下圖:

基于 FutureTask 獲取線程返回值

所以在這種情況之下,咱們玩兒多線程并發(fā)編程就必須引入 Future 這個(gè)東西了。

這個(gè) Future 呢,其實(shí)就代表了你對(duì)另外一個(gè)線程的控制權(quán),當(dāng)你開(kāi)啟一個(gè) thread 線程跑起來(lái)以后,你如果可以拿到一個(gè) Future,就可以通過(guò)這個(gè) Future 去控制那個(gè)線程。

比如說(shuō)中斷那個(gè) thread 線程的運(yùn)行,比如說(shuō)通過(guò) Future 拿到那個(gè)線程的返回值,等等。

如下圖:

所以這個(gè) Future 在我們用 Java 寫(xiě)多線程并發(fā)編程的時(shí)候,是必須要掌握的,因?yàn)榻?jīng)常會(huì)用到!下面我們來(lái)給大家介紹一下這個(gè) Future 在代碼中是怎么來(lái)用的!

首先,我們來(lái)寫(xiě)一段用于給 thread 子線程運(yùn)行的任務(wù)代碼,如下:

public class Task implements Callable {

public String call() throws Exception {
// 執(zhí)行一段任務(wù)代碼,然后得到一個(gè)結(jié)果,并且返回
System.out.println("模擬運(yùn)行任務(wù)代碼");
// 默認(rèn)任務(wù)代碼運(yùn)行一共耗時(shí)了500ms
Thread.sleep(500);
String result = "模擬返回結(jié)果";
return result;
}

}

接著我們來(lái)寫(xiě)一段代碼在 main 方法中用 FutureTask 開(kāi)啟一個(gè) thread 線程運(yùn)行上述代碼,并且通過(guò) Future 去拿到這個(gè) thread 線程運(yùn)行完畢代碼后返回的結(jié)果。

代碼如下:

public class FutureTaskTest {

public static void main(String[] args)
throws InterruptedException, ExecutionException {
// 基于我們自己寫(xiě)的任務(wù)代碼,構(gòu)建一個(gè)FutureTask,這個(gè)FutureTask說(shuō)白了
// 其實(shí)也是一個(gè)任務(wù),只不過(guò)是用這個(gè)JDK提供的FutureTask封裝了我們的任務(wù)代碼
FutureTask futureTask =
new FutureTask(new Task());
// 構(gòu)建一個(gè)線程池,線程池里會(huì)有一個(gè)真正運(yùn)行任務(wù)的線程的
ExecutorService threadPool = Executors.newFixedThreadPool(1);
// 把FutureTask任務(wù)提交到線程池里去,讓線程池里的線程運(yùn)行我們的任務(wù)代碼
threadPool.submit(futureTask);

// 這個(gè)地方我們可以模擬干了一些別的事情,執(zhí)行了很多別的代碼,過(guò)了一段時(shí)間
Thread.sleep(1000);

// 過(guò)了一段時(shí)間以后,線程池里的線程應(yīng)該運(yùn)行完畢我們提交的任務(wù)代碼了
// 此時(shí)就可以通過(guò)FutureTask來(lái)獲取到那個(gè)任務(wù)代碼運(yùn)行后的結(jié)果
System.out.println(futureTask.get());
}

}

總結(jié)

通過(guò)上面的代碼,大家就可以看到,當(dāng)我們用子線程運(yùn)行執(zhí)行的一段任務(wù)代碼時(shí),任務(wù)代碼運(yùn)行完畢后是可以返回一個(gè)值的。

然后我們只要用 FutureTask 封裝這個(gè)任務(wù)代碼,就可以在一段時(shí)間過(guò)后,通過(guò) FutureTask 拿到這個(gè)任務(wù)代碼運(yùn)行完畢后返回的值。

這是咱們 Java 多線程并發(fā)編程常用的一種編程技巧,希望大家今天能 get 到這個(gè) Future 的妙用。


分享名稱(chēng):Java多線程并發(fā)編程,一定要巧用Future!
瀏覽地址:http://www.5511xx.com/article/dpsodgh.html