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

Java19 帶來的虛擬線程是怎樣玩出花提升十倍性能的

開發(fā) 前端
虛擬線程的代碼跟上面的代碼十分相似,代碼如下??梢钥吹?,在代碼層面上跟上面唯一的區(qū)別就是 Executors.newCachedThreadPool() 這一行變成了 Executors.newVirtualThreadPerTaskExecutor() 即代表創(chuàng)建的虛擬線程。

今天阿粉想跟大家聊的時(shí)候 Java19 中提到的虛擬線程 virtual threads。

基本概念

我們都知道 Java 中的線程跟操作系統(tǒng)的內(nèi)核線程是一對一的,Java 線程的調(diào)度其實(shí)是依賴操作系統(tǒng)的內(nèi)核線程的,這就導(dǎo)致了我們的線程切換和運(yùn)行就需要進(jìn)行上下文切換以及消耗大量的系統(tǒng)資源,同時(shí)我們也知道機(jī)器的資源是昂貴的并且也是有限的,我們不能也無法肆無忌憚的創(chuàng)建線程,因此線程往往會成為我們系統(tǒng)的瓶頸。

圖片

為了解決這個(gè)問題,Java19 中提出了一種虛擬線程的概念,為了區(qū)別,之前的線程被稱為平臺線程。要注意虛擬線程并不是用來直接取代平臺線程的,虛擬線程是建議在平臺線程之上的,一個(gè)平臺線程可以對應(yīng)多個(gè)虛擬線程,同時(shí)一個(gè)平臺線程還是一一對應(yīng)內(nèi)核線程,因此上面的架構(gòu)就變成了如下,一個(gè) VT 代表一個(gè)虛擬線程。

圖片

如果有小伙伴對 GO 語言比較熟悉的話,就會想到 Java 中的虛擬線程跟 GO 中的 Goroutines 是很類似的,確實(shí)是這樣,所以說語言都是相通的。

舉個(gè)栗子

這里我們通過分別使用平臺線程以及虛擬線程來測試一個(gè) case 看看兩者的耗時(shí)和性能是怎樣的,測試分如下幾步,我們依次來看一下。注意下面的測試代碼都是在 Java19 的版本中運(yùn)行的。

平臺線程方式

我們通過 JDK 自帶的線程池 Executors.newCachedThreadPool() 來創(chuàng)建線程池,并執(zhí)行一定數(shù)據(jù)任務(wù),任務(wù)的數(shù)量我們通過入?yún)砜刂疲奖愫罄m(xù)通過主函數(shù)調(diào)用。

public static void platformThread(int size){
long l = System.currentTimeMillis();
try(var executor = Executors.newCachedThreadPool()) {
IntStream.range(0, size).forEach(i -> {
executor.submit(() -> {
Thread.sleep(Duration.ofSeconds(1));
//System.out.println(i);
return i;
});
});
}
System.out.printf("elapsed time: %dms\n", System.currentTimeMillis() - l);
}

虛擬線程的方式

虛擬線程的代碼跟上面的代碼十分相似,代碼如下??梢钥吹?,在代碼層面上跟上面唯一的區(qū)別就是 Executors.newCachedThreadPool()  這一行變成了 Executors.newVirtualThreadPerTaskExecutor() 即代表創(chuàng)建的虛擬線程。

public static void virThread(int size){
long l = System.currentTimeMillis();
try(var executor = Executors.newVirtualThreadPerTaskExecutor()) {
IntStream.range(0, size).forEach(i -> {
executor.submit(() -> {
Thread.sleep(Duration.ofSeconds(1));
//System.out.println(i);
return i;
});
});
}
System.out.printf("elapsed time: %dms\n", System.currentTimeMillis() - l);
}

監(jiān)控運(yùn)行的線程

上面的兩個(gè)方法都是都是創(chuàng)建線程池用來提交任務(wù)的,但是位于具體創(chuàng)建了多少個(gè)線程我們是不知道的,所以我們還需要通過下面的代碼來監(jiān)控。

public static void main(String[] args){
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);
scheduledExecutorService.scheduleAtFixedRate(() -> {
ThreadMXBean threadBean = ManagementFactory.getThreadMXBean();
ThreadInfo[] threadInfo = threadBean.dumpAllThreads(false, false);
long count = Arrays.stream(threadInfo).count();
System.out.println(count + " os thread");
}, 1, 1, TimeUnit.SECONDS);

int size = 100000;
// platformThread(size);
virThread(size);
}

通過另一個(gè)線程池開啟一個(gè)線程信息監(jiān)控的線程,每秒鐘輸出一次當(dāng)前的運(yùn)行線程數(shù)。這里注意,如果上面的代碼在 IDEA 中提示報(bào)錯(cuò),找不到類,如下所示,我們可以將鼠標(biāo)放上去進(jìn)行修復(fù)。

圖片

也可以手動在設(shè)置中的編譯器》Java 編譯器這里給自己的模塊增加一個(gè)編譯參數(shù) -parameters --add-modules java.management --enable-preview 。

圖片

運(yùn)行

上面的三段組合在一起就是一個(gè)完整的 case,如果這個(gè)時(shí)候如果上面的代碼都正常,在運(yùn)行的時(shí)候不出意外會出現(xiàn)下面的錯(cuò)誤,

圖片

這里是因?yàn)楫?dāng)前 Java19 中的虛擬線程特性還處于預(yù)覽階段,不能直接使用,我們需要在啟動參數(shù)上面配置 --enable-preview 參數(shù),才能正常測試,如下所示,不同版本的 IDEA 可能顯示的位置不一樣,但是都是配置 VM 參數(shù),找一下就好了。

圖片

配置好了過后再次運(yùn)行就可以得到如下的結(jié)果,可以看到在 size 大小為 100000 的情況下,虛擬線程只創(chuàng)建了 12 個(gè)平臺線程,并且只在 2523 ms 就完成了整個(gè)任務(wù)。

圖片

但是當(dāng)我們運(yùn)行平臺線程的方法的時(shí)候會發(fā)現(xiàn),同樣的 size 的情況下,平臺線程創(chuàng)建了好幾千個(gè),而且還會觸發(fā) OOM,因?yàn)椴僮飨到y(tǒng)的資源已經(jīng)被耗盡了,由此可見虛擬線程的性能要遠(yuǎn)遠(yuǎn)高于平臺線程。YYDS!

圖片

[ ] 為了避免OOM 我們也可以將代碼中的  Executors.newCachedThreadPool() 方法,改成 Executors.newFixedThreadPool(xxx),這樣雖然可以避免大量創(chuàng)建線程導(dǎo)致 OOM,但是任務(wù)執(zhí)行的時(shí)長就會消耗更長,阿粉這邊測試在 size 為 10000 的情況下,配置 500 個(gè)線程的時(shí)候,總共花費(fèi)了 20276 ms,在數(shù)據(jù)量小十倍的情況下耗時(shí)卻增長十倍。性能可想而知,感興趣的小伙伴可以自己嘗試一下。


圖片


責(zé)任編輯:武曉燕 來源: Java極客技術(shù)
相關(guān)推薦

2023-09-07 11:29:36

API開發(fā)

2017-09-26 14:56:57

MongoDBLBS服務(wù)性能

2024-06-27 11:22:34

2023-06-13 13:52:00

Java 7線程池

2025-03-13 11:59:00

2021-09-13 10:25:35

開發(fā)技能代碼

2017-12-06 08:06:47

IBMGPU機(jī)器學(xué)習(xí)

2023-02-07 20:17:21

JDK19虛擬線程

2021-04-13 14:25:41

架構(gòu)運(yùn)維技術(shù)

2023-02-06 07:17:22

2009-12-15 21:49:05

2024-03-08 07:58:13

QPShttpsync

2022-10-27 07:09:34

DjangoAPIRedis

2022-09-15 16:59:46

人工智能空調(diào)能源

2022-08-30 10:58:45

ViteEsbuild前端

2024-08-01 08:06:11

虛擬線程性能

2021-08-04 12:26:00

Postman工具頻率

2021-12-14 10:54:31

TopK面試排序法

2018-06-06 10:15:21

區(qū)塊鏈互聯(lián)網(wǎng)CCTV

2009-06-05 09:11:19

中國電信VDSL2ADSL
點(diǎn)贊
收藏

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