欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JDK21中虛擬線程到底是什么以及用法總結(jié)(看完便知)

 更新時間:2023年12月09日 09:32:24   作者:愛讀源碼的大都督  
這篇文章主要給大家介紹了關(guān)于JDK21中虛擬線程到底是什么以及用法的相關(guān)資料,虛擬線程是一種輕量化的線程封裝,由jvm直接調(diào)度和管理,反之普通的線程其實是調(diào)用的操作系統(tǒng)的能力,對應(yīng)的是操作系統(tǒng)級的線程,需要的朋友可以參考下

本文涉及到的技術(shù):虛擬線程、結(jié)構(gòu)化并發(fā)、線程池、TheadLocal,對原理感興趣的可以直接跳到原理部分。

虛擬線程是JDK19中引入的,JDK21正式發(fā)布,我們先來看看虛擬線程的幾種用法,然后再來分析底層實現(xiàn)原理。

先定義一個Runnable:

通過觀察輸出結(jié)果,就能知道當前運行Task的是不是虛擬線程。

也可以增加以下代碼直接判斷是不是虛擬線程:

Thread.ofVirtual()

手動開啟虛擬線程執(zhí)行任務(wù):

自動開啟虛擬線程執(zhí)行任務(wù):

兩者輸出結(jié)果類似,為:

根據(jù)名字可以看出確實是用的VirtualThread,但似乎跟ForkJoinPool有關(guān),后面會分析。

我們也可以通過以下方式來創(chuàng)建普通線程

輸出結(jié)果為:

確實是普通線程。

還可以先得到一個ThreadFactory,然后來創(chuàng)建虛擬線程:

輸出結(jié)果為:

還有一種更簡單的API:

輸出結(jié)果為:

結(jié)構(gòu)化并發(fā)

在JDK21中還有一個新特性(預(yù)覽版),叫做結(jié)構(gòu)化并發(fā),也會自動創(chuàng)建虛擬線程來運行代碼,比如:

輸出結(jié)果為:

Executors

還有一種和線程池類似的使用方式:

以上代碼中每個任務(wù)運行時都會開啟一個虛擬線程,輸出結(jié)果為:

表示有3個虛擬線程。

虛擬線程底層原理

以上大概就是使用或創(chuàng)建虛擬線程的幾種情況了,那到底什么是虛擬線程呢?它跟線程有什么關(guān)系?它跟ForkJoinPool又有什么關(guān)系呢?

虛擬線程畢竟是虛擬的,就像虛擬機也是虛擬的,是需要真實操作系統(tǒng)來支撐運行的。而虛擬線程仍然是基于線程來進行調(diào)度執(zhí)行的

我們先來看看普通線程的缺點在哪,看下面代碼:

假如是一個普通線程執(zhí)行上述代碼,在輸出完“before”后,線程就會睡眠1秒,然后才會輸出“after”,如果是一個線程要執(zhí)行3個這樣的任務(wù),比如:

生成一個只有一個線程的線程池,用它來執(zhí)行三個任務(wù),實際上就是串行執(zhí)行這三個任務(wù),輸出結(jié)果為:

但是,我們好好想想:當這個普通線程執(zhí)行完第一個任務(wù)的“before”后,需要等1s才執(zhí)行“after”,那能不能在等1s的過程中去執(zhí)行第二個任務(wù)的“before”呢?原則上是可以的,這就是虛擬線程要優(yōu)化的點。

大家好好理解一下上面的這句話,這是精髓

我們來看改成虛擬線程后的運行效果,先修改Task:

然后運行:

輸出結(jié)果為:

大家運行時可能會發(fā)現(xiàn)有多個不同的ForkJoinPool-1-worker,那是因為我做了配置,后面會解釋

不知道大家能不能看懂這個效果,我們可以發(fā)現(xiàn)有3個虛擬線程:VirtualThread[#21]、VirtualThread[#23]、VirtualThread[#24],但是只有一個線程:ForkJoinPool-1-worker-1,雖然只有一個線程,卻達到了并行執(zhí)行三個任務(wù)的效果,其原理就是上面所分析的:

線程先執(zhí)行任務(wù)1,任務(wù)1睡眠的過程中,線程會去執(zhí)行任務(wù)2任務(wù)2睡眠的過程中,線程會去執(zhí)行任務(wù)3任務(wù)3睡眠的過程中,線程暫時沒有任務(wù)執(zhí)行了過一會,任務(wù)1睡眠結(jié)束,線程繼續(xù)執(zhí)行任務(wù)1然后,任務(wù)2睡眠結(jié)束,線程繼續(xù)執(zhí)行任務(wù)2最后,任務(wù)3睡眠結(jié)束,線程繼續(xù)執(zhí)行任務(wù)3

這樣就達到了一個線程并行執(zhí)行三個任務(wù)的效果,從中,我們可以看到,線程需要知道:一個任務(wù)什么時候開始睡眠了,什么時候睡眠結(jié)束了,哪個任務(wù)還沒開始執(zhí)行,哪個任務(wù)已經(jīng)在執(zhí)行中了?

但是,任務(wù)是程序員所定義的,所以就需要虛擬線程來封裝任務(wù),而線程只關(guān)心虛擬線程即可,也就是線程負責來調(diào)度各個虛擬線程的執(zhí)行,也就是來判斷虛擬線程是不是睡眠了?是不是正在運行?

我們可以把虛擬線程理解為一個對象,這個虛擬線程對象有幾種狀態(tài),比如是不是睡眠中,是不是運行中,而一個線程可以支持同時運行多個虛擬線程對象,當線程發(fā)現(xiàn)某個虛擬線程對象睡眠時,就會去運行其他的虛擬線程對象。

或者這么說:虛擬線程sleep了,底層的線程并不一定sleep了。

所以,虛擬線程就是線程調(diào)度的單位,一個線程可以調(diào)度很多個虛擬線程,如果有多個線程,那當然就能調(diào)度更多虛擬線程了,所以在JDK的實現(xiàn)中,使用ForkJoinPool來提供線程作為虛擬線程的調(diào)度者,同時由于ForkJoinPool的任務(wù)竊取機制,能進一步提高任務(wù)并行執(zhí)行的效率。

默認情況下,這個ForkJoinPool中的線程數(shù)等于CPU核心數(shù),我們可以通過以下參數(shù)來修改:

  • -Djdk.virtualThreadScheduler.parallelism=1
  • -Djdk.virtualThreadScheduler.maxPoolSize=1

另外,虛擬線程也不用考慮池化,因為它不像線程,開啟和關(guān)閉一個線程是需要調(diào)用操作系統(tǒng)的,而虛擬線程跟操作系統(tǒng)沒關(guān)系。

再另外,JDK21中的虛擬線程也支持ThreadLocal,也就是一個虛擬線程在執(zhí)行任務(wù)的過程中,也可以通過ThreadLocal來共享數(shù)據(jù),使得我們在開發(fā)過程中就把虛擬線程當作普通線程使用就可以了。

還有要注意的是,當任務(wù)進行網(wǎng)絡(luò)IO、磁盤IO時也相當是sleep了,所以如果虛擬線程用到真實項目中,就能做到用少量線程支撐較高的并發(fā),從而能大大提高項目的吞吐量,虛擬線程不是用來提速的,而是用來提高吞吐量的

總結(jié)

到此這篇關(guān)于JDK21中虛擬線程到底的文章就介紹到這了,更多相關(guān)JDK21虛擬線程用法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • springboot+vue項目怎么解決跨域問題詳解

    springboot+vue項目怎么解決跨域問題詳解

    這篇文章主要介紹了springboot+vue項目怎么解決跨域問題的相關(guān)資料,包括前端代理、后端全局配置CORS、注解配置和Nginx反向代理,并總結(jié)了每種方法的適用場景、優(yōu)點和缺點,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2025-05-05
  • java中有無參數(shù)和返回值的方法詳解

    java中有無參數(shù)和返回值的方法詳解

    這篇文章主要介紹了java中有無參數(shù)和返回值的方法詳解,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • 使用JPA自定義SQL查詢結(jié)果

    使用JPA自定義SQL查詢結(jié)果

    這篇文章主要介紹了使用JPA自定義SQL查詢結(jié)果,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • JPA配置詳解之jpaProperties用法

    JPA配置詳解之jpaProperties用法

    這篇文章主要介紹了JPA配置詳解之jpaProperties用法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • spring boot如何基于JWT實現(xiàn)單點登錄詳解

    spring boot如何基于JWT實現(xiàn)單點登錄詳解

    這篇文章主要介紹了spring boot如何基于JWT實現(xiàn)單點登錄詳解,用戶只需登錄一次就能夠在這兩個系統(tǒng)中進行操作。很明顯這就是單點登錄(Single Sign-On)達到的效果,需要的朋友可以參考下
    2019-06-06
  • spring mvc中的@ModelAttribute注解示例介紹

    spring mvc中的@ModelAttribute注解示例介紹

    在Spring mvc中,注解@ModelAttribute是一個非常常用的注解,下面這篇文章主要給大家介紹了關(guān)于spring mvc中@ModelAttribute注解的相關(guān)資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下。
    2017-09-09
  • Spring用代碼來讀取properties文件實例解析

    Spring用代碼來讀取properties文件實例解析

    這篇文章主要介紹了Spring用代碼來讀取properties文件實例解析,具有一定借鑒價值,需要的朋友可以參考下
    2018-01-01
  • 關(guān)于Java反射給泛型集合賦值問題

    關(guān)于Java反射給泛型集合賦值問題

    這篇文章主要介紹了Java反射給泛型集合賦值,需要的朋友可以參考下
    2022-01-01
  • Springboot下使用Redis管道(pipeline)進行批量操作

    Springboot下使用Redis管道(pipeline)進行批量操作

    本文主要介紹了Spring?boot?下使用Redis管道(pipeline)進行批量操作,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-05-05
  • Spring如何將配置文件中的簡單值注入Bean中

    Spring如何將配置文件中的簡單值注入Bean中

    Spring 提供了幾種優(yōu)雅的方式來將配置文件中的簡單值(如字符串、數(shù)字、布爾值等)注入到 Bean 中,下面小編就為大家介紹一下兩種主流的方法吧
    2025-07-07

最新評論