自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Java多線程并發(fā)編程,一定要巧用Future!

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

大家好,今天跟大家聊聊 Java 里面的多線程并發(fā)編程,這個多線程并發(fā)編程,想必大家都是懂的,說白了,就是在代碼里開啟一個新的線程去執(zhí)行一段代碼,然后那段代碼什么時候被執(zhí)行完畢,你可能也不太清楚,但是他總會過一段時間之后執(zhí)行完畢的。

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

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

其實(shí)這個問題,我們必須得從 main 方法開始說起,簡單來說,你寫一段 Java 代碼,其實(shí)一般來說啟動和執(zhí)行這些 Java 代碼,都必須去運(yùn)行一個 main 方法對不對,而且現(xiàn)在比較流行這個 SpringBoot,其實(shí) SpringBoot 也是基于 main 方法來啟動的。

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

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

如下圖:

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

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

如下圖:

多線程編程是什么?

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

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

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

如下圖:

那么這個時候問題來了,對于你的 main 線程來說,開了一個 thread 線程去執(zhí)行部分代碼。

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

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

如下圖:

基于 FutureTask 獲取線程返回值

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

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

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

如下圖:

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

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

public class Task implements Callable<String> {

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

}

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

代碼如下:

public class FutureTaskTest {

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

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

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

}

總結(jié)

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

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

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

責(zé)任編輯:武曉燕 來源: 石杉的架構(gòu)筆記
相關(guān)推薦

2011-11-18 10:50:25

設(shè)計(jì)模式Java線程

2023-10-08 09:34:11

Java編程

2023-10-18 15:19:56

2013-07-16 10:12:14

iOS多線程多線程概念多線程入門

2022-06-02 11:12:10

CallableFuture

2009-03-12 10:52:43

Java線程多線程

2025-02-17 00:00:25

Java并發(fā)編程

2025-02-19 00:05:18

Java并發(fā)編程

2017-05-05 09:26:33

2011-12-29 13:31:15

Java

2010-11-19 16:02:42

IT族

2018-10-25 15:55:44

Java多線程鎖優(yōu)化

2022-07-29 08:58:44

多線程并發(fā)

2024-05-10 08:10:05

Spring虛擬線程JDK

2020-12-07 09:40:19

Future&Futu編程Java

2009-02-24 08:36:51

多線程線程池網(wǎng)絡(luò)服務(wù)器

2009-07-29 16:42:35

Java多線程編程

2011-07-22 14:55:20

多線程

2011-06-13 10:41:17

JAVA

2022-07-20 07:45:15

多線程程序性能
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號