成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Java 21:虛擬線程介紹

開發(fā) 前端
盡管作用域值 (JEP 446) 和結(jié)構(gòu)化并發(fā) (JEP 453) 仍然是 Java 21 中的預(yù)覽功能,但虛擬線程已經(jīng)成為可投入生產(chǎn)的成熟功能。

Java 21 版本更新中最重要的功能之一就是虛擬線程 (JEP 444)。這些輕量級(jí)線程減少了編寫、維護(hù)和觀察高吞吐量并發(fā)應(yīng)用程序所需的工作量。

正如我的許多其他文章一樣,在推出新功能之前,讓我們先看看 Java 21 版本更新前的現(xiàn)狀,以便更好地了解 Java 21 版本試圖解決的問題以及好處是什么。

平臺(tái)線程

在引入虛擬線程之前,java.lang.Thread 包已經(jīng)支持所謂的平臺(tái)線程。

這些線程通常以 1:1 的方式映射到操作系統(tǒng)調(diào)度的內(nèi)核線程。操作系統(tǒng)線程相當(dāng)“重”。這使得它們可以執(zhí)行所有類型的任務(wù)。

根據(jù)操作系統(tǒng)和 JVM 啟動(dòng)參數(shù)配置的不同,一個(gè)平臺(tái)線程默認(rèn)消耗 1 MB 的空間。因此如果我們想在重負(fù)載高并發(fā)應(yīng)用程序中使用一百萬個(gè)線程,我們最好有超過 1 TB 的空閑內(nèi)存!

如上所述,平臺(tái)線程有一個(gè)明顯的內(nèi)存瓶頸限制了我們實(shí)際上可以擁有的線程數(shù)量。

每個(gè)請(qǐng)求一個(gè)線程

每個(gè)請(qǐng)求使用單個(gè)線程有很多優(yōu)點(diǎn),例如更容易的狀態(tài)管理和清理。但它也造成了可擴(kuò)展性限制。應(yīng)用程序的“并發(fā)單元”(在本例中為請(qǐng)求)需要單個(gè)“并發(fā)平臺(tái)單元”(在本例中也就是平臺(tái)線程),但是在重負(fù)載高并發(fā)應(yīng)用程序中,平臺(tái)線程容易因?yàn)閮?nèi)存不足、CPU 資源耗盡而創(chuàng)建失敗。

盡管“每個(gè)請(qǐng)求一個(gè)線程”有很多優(yōu)點(diǎn),平臺(tái)線程可以更均勻地利用硬件,但我們還是需要一種完全不同的方法。

使用線程池

與在單個(gè)線程上處理以個(gè)請(qǐng)求不同,當(dāng)任務(wù)完成時(shí),線程會(huì)被線程池回收,因此另一個(gè)請(qǐng)求可能會(huì)重用相同的線程。這允許我們的程序使用更少的線程處理更多的請(qǐng)求,但會(huì)帶來異步編程的負(fù)擔(dān)。

異步編程具有自己的范例,具有一定的學(xué)習(xí)曲線,并且可能使我們的程序更難以理解和遵循。請(qǐng)求的每個(gè)部分可能在不同的線程上執(zhí)行,在沒有合理上下文的情況下創(chuàng)建堆棧跟蹤,并使調(diào)試變得非常棘手甚至幾乎不可能。

重新審視“每個(gè)請(qǐng)求一個(gè)線程”模型,很明顯,我們需要一種更輕量級(jí)的線程方法來解決這個(gè)瓶頸,并最好按照我們熟悉的方式。

輕量級(jí)線程

由于平臺(tái)線程的數(shù)量在不新增硬件資源的情況下無法改變,因此也就需要另一層抽象,以切斷首先產(chǎn)生瓶頸的可怕的 1:1 映射。

輕量級(jí)線程不依賴于特定的平臺(tái)線程,也不會(huì)為其分配大量?jī)?nèi)存。它們由運(yùn)行時(shí)的 JVM 調(diào)度和管理而不是底層操作系統(tǒng)。這就是為什么可以創(chuàng)建大量輕量級(jí)線程的原因。

輕量級(jí)線程的概念并不新鮮,許多語(yǔ)言都有某種形式的輕量級(jí)線程:

  • Go 語(yǔ)言中的 Goroutines(協(xié)程)
  • Erlang 語(yǔ)言中的 Processes(輕量級(jí)進(jìn)程)
  • Haskell Threads

Java 也在 21 版本中引入了自己的輕量級(jí)線程實(shí)現(xiàn):虛擬線程。

虛擬線程

虛擬線程是一個(gè)新的輕量級(jí) java.lang.Thread 變體,是 Project Loom 項(xiàng)目的一部分,不由操作系統(tǒng)管理或調(diào)度。相反由 JVM 負(fù)責(zé)調(diào)度。當(dāng)然在實(shí)際工作反映到操作系統(tǒng)還是以平臺(tái)線程運(yùn)行,但 JVM 正是利用所謂的載體線程(即平臺(tái)線程)來“承載”虛擬線程,以便在需要時(shí)執(zhí)行。

JVM / OS 線程調(diào)度示意圖JVM / OS 線程調(diào)度示意圖

所需的平臺(tái)線程以 FIFO 工作方式在 ForkJoinPool 中進(jìn)行管理,默認(rèn)情況下,它使用所有可用的處理器,但可以通過調(diào)整系統(tǒng)屬性 jdk.virtualThreadScheduler.parallelism 來根據(jù)我們的要求進(jìn)行修改。我們熟悉的 ForkJoinPool 與并行流等其他功能使用的公共池之間的主要區(qū)別在于,公共池以 LIFO 模式運(yùn)行。

物美價(jià)廉

虛擬線程是廉價(jià)且輕量級(jí)的,我們可以使用“每個(gè)請(qǐng)求一個(gè)線程”模型,而不必?fù)?dān)心實(shí)際需要多少個(gè)線程。如果我們的代碼在虛擬線程中調(diào)用阻塞 I/O 操作,則運(yùn)行時(shí)會(huì)掛起這個(gè)被阻塞的虛擬線程,直到掛起結(jié)束后就可以恢復(fù)。這樣一來,程序?qū)τ布睦镁涂梢赃_(dá)到近乎最佳并提供高水平的并發(fā)性,從而實(shí)現(xiàn)高吞吐量。

因?yàn)樘摂M線程非常便宜,所以虛擬線程不會(huì)被重用或需要被池化。每個(gè)任務(wù)都由其自己的虛擬線程來執(zhí)行。

設(shè)定界限

JVM 調(diào)度程序通過載體線程來管理虛擬線程,因此需要一定的邊界和分隔來確保可能的“無數(shù)”虛擬線程按預(yù)期運(yùn)行。這是通過在載體線程和它可能承載的任何虛擬線程之間保持無線程關(guān)聯(lián)來實(shí)現(xiàn)的:

  • 虛擬線程無法訪問載體線程,Thread.currentThread() 返回虛擬線程本身。
  • 堆棧跟蹤是獨(dú)立的,虛擬線程中拋出的任何異常僅包含其自己的堆棧幀。
  • 虛擬線程的線程局部變量對(duì)其載體線程不可用,反之亦然。
  • 從代碼的角度來看,載體線程及其虛擬線程對(duì)平臺(tái)線程的共享是不可見的。

代碼展示

在我看來,虛擬線程最好的事情之一就是我們不需要學(xué)習(xí)新的編程范例或復(fù)雜的新 API,就能夠完成異步編程。在使用上,我們可以像對(duì)待平臺(tái)線程一樣對(duì)待虛擬線程。

創(chuàng)建平臺(tái)線程

創(chuàng)建平臺(tái)線程很簡(jiǎn)單,就像使用 Runnable 創(chuàng)建一樣:

Runnable fn = () -> {
  // your code here
};

Thread thread = new Thread(fn).start();

隨著 Project Loom 項(xiàng)目簡(jiǎn)化了新的并發(fā)方法,還提供了一種創(chuàng)建平臺(tái)線程的新方法:

Thread thread = Thread.ofPlatform().
                      .start(runnable);

實(shí)際上,現(xiàn)在有一個(gè)完整的 Fluent API,因?yàn)?nbsp;ofPlatform() 返回一個(gè) Thread.Builder.OfPlatform 實(shí)例:

Thread thread = Thread.ofPlatform().
                      .daemon()
                      .name("my-custom-thread")
                      .unstarted(runnable);

但你來這里顯然不是為了學(xué)習(xí)創(chuàng)建“舊”線程的新方法,你想要新的東西!

創(chuàng)建虛擬線程

對(duì)于虛擬線程,同樣有一個(gè) Fluent API:

Runnable fn = () -> {
  // your code here
};

Thread thread = Thread.ofVirtual(fn)
                      .start();

除了構(gòu)建器方法之外,我們還可以直接使用以下命令創(chuàng)建虛擬線程:

Thread thread = Thread.startVirtualThread(() -> {
  // your code here
});

由于所有虛擬線程始終都是守護(hù)線程,因此如果我們想在主線程上等待虛擬線程執(zhí)行完畢,可以調(diào)用 join() 方法。

創(chuàng)建虛擬線程的另一種方法是使用 Executor 類:

var executorService = Executors.newVirtualThreadPerTaskExecutor();

executorService.submit(() -> {
  // your code here
});

總結(jié)

盡管作用域值 (JEP 446) 和結(jié)構(gòu)化并發(fā) (JEP 453) 仍然是 Java 21 中的預(yù)覽功能,但虛擬線程已經(jīng)成為可投入生產(chǎn)的成熟功能。

虛擬線程是一種通用且強(qiáng)大的 Java 并發(fā)新方式,將對(duì)我們的未來程序產(chǎn)生重大影響。虛擬線程使用熟悉且可靠的“每個(gè)請(qǐng)求一個(gè)線程”方法,同時(shí)以最佳方式利用所有可用硬件,無需學(xué)習(xí)新范例或復(fù)雜的 API。

本文翻譯自國(guó)外論壇 medium,原文地址:https://medium.com/@benweidig/looking-at-java-21-virtual-threads-0ddda4ac1be1

責(zé)任編輯:武曉燕 來源: waynblog
相關(guān)推薦

2023-10-23 19:51:11

Java線程

2023-12-28 08:45:25

虛擬線程Java 21

2023-12-08 08:07:48

Java 21虛擬線程

2023-09-20 09:07:01

Java 21開發(fā)工具包

2023-09-26 12:16:29

JDK 21Java

2024-06-06 16:15:00

2011-07-22 14:55:20

多線程

2023-12-28 10:49:27

響應(yīng)式編程異步

2011-06-22 13:35:55

JVM

2010-03-17 15:34:09

Java線程同步引用

2010-03-19 17:47:02

Java Socket

2012-05-15 02:18:31

Java線程池

2023-11-03 18:23:34

虛擬線程服務(wù)器

2010-03-18 14:09:20

Java線程同步

2010-03-18 15:47:07

Java創(chuàng)建線程

2010-03-17 19:24:38

Java多線程循環(huán)

2024-01-12 16:12:44

Java虛擬線程開發(fā)

2009-07-15 18:06:38

Swing線程

2010-03-16 10:10:57

Java線程通信

2010-03-15 19:11:39

Java多線程語(yǔ)句
點(diǎn)贊
收藏

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

主站蜘蛛池模板: 久久99精品久久久久 | 激情五月综合 | 一区二区不卡视频 | 精品久| 五月天综合网 | 亚洲性在线 | 精品国产91乱码一区二区三区 | 亚洲视频免费 | 久久99精品久久久久久 | 午夜视频一区二区三区 | 尤物视频在线免费观看 | a级免费黄色片 | 国产高清在线精品一区二区三区 | 精精久久 | 精品中文字幕一区二区三区 | 精品国产免费一区二区三区五区 | 日韩理论电影在线观看 | av男人天堂影院 | 精品国产一区二区三区久久久蜜月 | 久久精品欧美一区二区三区不卡 | 天天干天天色 | 国产成人综合久久 | 五月激情婷婷网 | 亚洲xxxxx| 国产91在线 | 亚洲 | 国产精品久久久久久52avav | 婷婷丁香激情 | 午夜丰满寂寞少妇精品 | 欧美日韩电影一区二区 | 超碰操| 一区二区三区久久久 | 日韩看片 | 婷婷去俺也去 | 成年人的视频免费观看 | 二区在线观看 | 欧美日韩精品一区 | 亚洲一区二区高清 | 欧美日韩亚洲成人 | 免费久久久 | 日韩视频一区 | 亚洲精品一区二区三区在线 |