最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

一文詳解JDK21中虛擬線程

 更新時(shí)間:2023年10月03日 10:03:47   作者:離離原上草77  
虛擬線程是JDK19中引入的,JDK21正式發(fā)布,本文主要介紹了JDK21中虛擬線程,具有一定的參考價(jià)值,感興趣的可以了解一下

JEP 425: Virtual Threads (Preview) 虛擬線程,輕量級(jí)的線程模型對(duì)標(biāo)其他語(yǔ)言中的協(xié)程,能夠顯著的減少編寫、維護(hù)和觀察高并發(fā)應(yīng)用程序的工作量。

該特性的目標(biāo):

  • 支持服務(wù)端應(yīng)用程序以thread-per-request樣式編寫,并最大限度壓榨硬件性能。
  • 兼容java.lang.Thread API,減少調(diào)用方代碼改動(dòng)。
  • 兼容現(xiàn)有的JDK工具,用于故障排查、調(diào)整和分析。
  • 不會(huì)替代線程的傳統(tǒng)實(shí)現(xiàn),也不會(huì)靜默升級(jí)現(xiàn)有的線程模型
  • 不會(huì)改變Java的并發(fā)編程模型
  • 在Java語(yǔ)言或Java庫(kù)中提供新的數(shù)據(jù)并行結(jié)構(gòu),不會(huì)動(dòng)搖Stream API的地位。

創(chuàng)建虛擬線程

虛擬線程并沒(méi)有引入獨(dú)立的API,而是選擇兼容Thread的API。這樣已有應(yīng)用程序只需要做最小的改動(dòng)就能使用協(xié)程帶來(lái)的好處。

Thread thread = Thread.ofVirtual().name("duke").unstarted(runnable);
Thread.startVirtualThread(Runnable)
Thread.isVirtual()

為了支持虛擬線程,Thread API被稍微修改,ThreadGroup不再支持

虛擬線程vs平臺(tái)線程

虛擬線程適合大量任務(wù)數(shù),低CPU負(fù)載的任務(wù)。如果是CPU為瓶頸的應(yīng)用,使用協(xié)程不會(huì)有性能改進(jìn)。

虛擬線程的調(diào)度

Java虛擬線程采用M:N模式,即M個(gè)協(xié)程在N個(gè)線程中運(yùn)行。調(diào)度線程默認(rèn)和核心數(shù)一樣多??梢酝ㄟ^(guò) system property jdk.virtualThreadScheduler.parallelism來(lái)配置。

虛擬線程的載體線程不是固定的,在生命其中可能運(yùn)行在不同的載體線程中。載體(carrier)線程和虛擬線程的堆棧信息是分離的,不會(huì)相互影響。

ThreadLocal和currentThread獲取的都是獨(dú)立的。在java代碼曾來(lái)說(shuō)虛擬線程后面的系統(tǒng)線程是不可見的。

虛擬線程的執(zhí)行

虛擬線程會(huì)在IO阻塞或者其他等待的時(shí)候掛起,在可用的時(shí)候恢復(fù)執(zhí)行。這不會(huì)阻塞載體線程,載體線程會(huì)去運(yùn)行新任務(wù)。受限于系統(tǒng),個(gè)別的阻塞操作可能也會(huì)阻塞載體線程,這時(shí)候可能會(huì)臨時(shí)擴(kuò)大調(diào)度池的大小。

一些情況下會(huì)釘住(pinned)載體線程,當(dāng)同步方法/塊或者當(dāng)執(zhí)行本地/外部函數(shù)時(shí)。被釘住的虛擬線程在執(zhí)行很多操作的時(shí)候會(huì)阻塞背后的系統(tǒng)線程。高頻或者長(zhǎng)時(shí)間的synchronized使用java.util.concurrent.locks.ReentrantLock來(lái)代替,可以減少釘住。

JDK Flight Recorder可以查看被釘住的線程。-Djdk.tracePinnedThreads=full參數(shù)將能獲取到完整的釘住線程的堆棧信息。將來(lái)可能會(huì)改進(jìn)pinning inside synchronized的情況。

內(nèi)存使用和垃圾收集器

虛擬線程的堆棧分配在垃圾收集的堆上。棧在運(yùn)行時(shí)的增長(zhǎng)和縮減,所以占用的內(nèi)存少,非常的高效。

虛擬線程不是垃圾收集的根,不再使用的虛擬線程將會(huì)被回收掉。

由于虛擬線程通常比較多,Thread-local開銷就會(huì)比較大,需要謹(jǐn)慎使用。

已有應(yīng)用遷移到虛擬線程

只需要三步:

1.將普通線程的創(chuàng)建改成創(chuàng)建虛擬線程。

2.取消池化機(jī)制。因?yàn)樘摂M線程非常輕量級(jí),不需要池化。

3.synchronized改為ReentrantLock,以減少被釘住。被釘住的虛擬線程容易阻塞背后的載體線程。

和async/await的比較

async/await比有棧協(xié)程在某些情況下更好用。例如請(qǐng)求c需要a和b作為參數(shù)的情況下,async/await比有棧協(xié)程實(shí)現(xiàn)起來(lái)更加簡(jiǎn)單直接:

a = requestA()
b = requestB()
c = await request(await a, await b)

寫一個(gè)簡(jiǎn)單的例子,開n個(gè)虛擬線程,每個(gè)線程sleep 1秒后累加1次,以模擬IO密集型操作。

    private static void runVirtualThread(int length) {
        AtomicInteger ai = new AtomicInteger();
        long start = System.currentTimeMillis();
        try (ExecutorService es = Executors.newVirtualThreadPerTaskExecutor()) {
            for (int i = 0; i < length; i++) {
                es.submit(() -> {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    if (ai.incrementAndGet() >= length) {
                        System.out.printf("duration=%d ms, done.%n", System.currentTimeMillis() - start);
                    }
                });
            }
        }
    }

然后再使用ScheduledExecutorService配合JMXBean打印JVM線程狀態(tài)

        ScheduledExecutorService se = Executors.newScheduledThreadPool(1);
        se.scheduleAtFixedRate(() -> {
            ThreadMXBean threadBean = ManagementFactory.getThreadMXBean();
            ThreadInfo[] threadInfo = threadBean.dumpAllThreads(false, false);
            System.out.printf("threadNumber=%d%n", threadInfo.length);
        }, 100, 1000, TimeUnit.MILLISECONDS);
        runVirtualThread(100000);
        // runThread(100000);
        Thread.sleep(100 * 1000);
        se.shutdownNow();

再寫一個(gè)使用傳統(tǒng)操作系統(tǒng)線程的對(duì)比程序

    private static void runThread(int length) {
        AtomicInteger ai = new AtomicInteger();
        long start = System.currentTimeMillis();
        try (ExecutorService es = Executors.newCachedThreadPool()) {
            for (int i = 0; i < length; i++) {
                es.submit(() -> {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    if (ai.incrementAndGet() >= length) {
                        System.out.printf("duration=%d ms, done.%n", System.currentTimeMillis() - start);
                    }
                });
            }
        }
    }

執(zhí)行

分別執(zhí)行虛擬線程和操作系統(tǒng)線程,入?yún)ength為100,000,執(zhí)行環(huán)境為Win11,Intel i5-12600KF。

  • 使用虛擬線程時(shí)輸出如下:

 threadNumber=26
threadNumber=26
threadNumber=26
threadNumber=26
duration=3530 ms, done.

  • 操作系統(tǒng)線程時(shí)輸出如下:

 threadNumber=2613
threadNumber=11072
threadNumber=15925
threadNumber=19725
threadNumber=22336
threadNumber=23933
duration=11614 ms, done.

結(jié)論

分別執(zhí)行10次并刪除壞點(diǎn)后,執(zhí)行結(jié)果如下:

線程類型執(zhí)行時(shí)間(ms)JVM線程數(shù)量打開句柄數(shù)量
虛擬線程3,40026600
操作系統(tǒng)線程11,50023000124,000

如上表所示,虛擬線程在執(zhí)行IO密集型高并發(fā)任務(wù)時(shí),性能遠(yuǎn)優(yōu)于操作系統(tǒng)線程方式,對(duì)于操作系統(tǒng)資源的占用也降低很多.

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

相關(guān)文章

  • springboot整合redis過(guò)期key監(jiān)聽實(shí)現(xiàn)訂單過(guò)期的項(xiàng)目實(shí)踐

    springboot整合redis過(guò)期key監(jiān)聽實(shí)現(xiàn)訂單過(guò)期的項(xiàng)目實(shí)踐

    現(xiàn)在各種電商平臺(tái)都有自己的訂單過(guò)期時(shí)間設(shè)置,那么如何設(shè)置訂單時(shí)間過(guò)期呢,本文主要介紹了springboot整合redis過(guò)期key監(jiān)聽實(shí)現(xiàn)訂單過(guò)期的項(xiàng)目實(shí)踐,感興趣的可以了解一下
    2023-12-12
  • Spring MVC多種情況下進(jìn)行文件上傳的實(shí)例

    Spring MVC多種情況下進(jìn)行文件上傳的實(shí)例

    上傳是Web工程中很常見的功能,SpringMVC框架簡(jiǎn)化了文件上傳的代碼,本文給大家總結(jié)了Spring MVC多種情況下進(jìn)行文件上傳的實(shí)例,并通過(guò)代碼示例給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2024-02-02
  • Java 爬蟲如何爬取需要登錄的網(wǎng)站

    Java 爬蟲如何爬取需要登錄的網(wǎng)站

    這篇文章主要介紹了Java 爬蟲如何爬取需要登錄的網(wǎng)站,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-10-10
  • Java使用反射操作數(shù)組示例

    Java使用反射操作數(shù)組示例

    這篇文章主要介紹了Java使用反射操作數(shù)組,結(jié)合實(shí)例形式分析了基于java反射機(jī)制操作數(shù)組的創(chuàng)建、賦值、輸出等相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2019-07-07
  • SpringBoot沒(méi)有讀取到application.yml問(wèn)題及解決

    SpringBoot沒(méi)有讀取到application.yml問(wèn)題及解決

    這篇文章主要介紹了SpringBoot沒(méi)有讀取到application.yml問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • Java 中使用同步線程的多種實(shí)現(xiàn)方式

    Java 中使用同步線程的多種實(shí)現(xiàn)方式

    本文主要介紹了Java 中使用同步線程的多種實(shí)現(xiàn)方式,包括synchronized關(guān)鍵字、ReentrantLock、ReentrantReadWriteLock、Atomic類、CyclicBarrier及Object的wait/notify方法,具有一定的參考價(jià)值,感興趣的可以了解一下
    2025-09-09
  • springboot CompletableFuture并行計(jì)算及使用方法

    springboot CompletableFuture并行計(jì)算及使用方法

    CompletableFuture基于 Future 和 CompletionStage 接口,利用線程池、回調(diào)函數(shù)、異常處理、組合操作等機(jī)制,提供了強(qiáng)大而靈活的異步編程功能,這篇文章主要介紹了springboot CompletableFuture并行計(jì)算及使用方法,需要的朋友可以參考下
    2024-05-05
  • 基于java實(shí)現(xiàn)DFA算法代碼實(shí)例

    基于java實(shí)現(xiàn)DFA算法代碼實(shí)例

    這篇文章主要介紹了基于java實(shí)現(xiàn)DFA算法代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-09-09
  • java去掉文本中多余的空格與空行實(shí)例代碼

    java去掉文本中多余的空格與空行實(shí)例代碼

    在最近的一個(gè)項(xiàng)目中發(fā)現(xiàn)用戶提交的數(shù)據(jù)中多了很多多余的空格與空行,為了不影響使用,只能想辦法去掉了,下面這篇文章主要給大家介紹了關(guān)于java去掉文本中多余的空格與空行的相關(guān)資料,需要的朋友可以參考借鑒,下面來(lái)一起看看吧。
    2017-08-08
  • 在Minio以STS方式獲得臨時(shí)憑據(jù)過(guò)程

    在Minio以STS方式獲得臨時(shí)憑據(jù)過(guò)程

    MinIO通過(guò)STS(Security Token Service)機(jī)制提供臨時(shí)訪問(wèn)憑證,提升安全性,臨時(shí)憑證具有時(shí)效性、權(quán)限受限和不可長(zhǎng)期持有的特點(diǎn),有效避免長(zhǎng)期密鑰泄露和精細(xì)化權(quán)限控制,MinIO兼容AWSS3的STS API,無(wú)需額外部署組件,通過(guò)創(chuàng)建策略和用戶并綁定策略
    2026-01-01

最新評(píng)論

锡林浩特市| 徐汇区| 措美县| 中山市| 砚山县| 兰州市| 定日县| 郁南县| 土默特左旗| 淮安市| 保德县| 山丹县| 三门峡市| 甘洛县| 荔浦县| 绥化市| 大城县| 手机| 松潘县| 军事| 阿克陶县| 白城市| 壶关县| 敦化市| 漠河县| 上高县| 黔东| 广州市| 太原市| 棋牌| 思茅市| 夏河县| 凯里市| 东乌珠穆沁旗| 平利县| 广德县| 岐山县| 满城县| 阿拉善左旗| 寿光市| 襄城县|