日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長提供免費收錄網(wǎng)站服務(wù),提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

什么是虛擬線程

虛擬線程是JAVA19開始增加的一個特性,和Golang的攜程類似,一個其它語言早就提供的、且如此實用且好用的功能,作為一個Java開發(fā)者,早就已經(jīng)望眼欲穿了。

虛擬線程和普通線程的區(qū)別

“虛擬”線程,望文生義,它是“假”的,它不直接調(diào)度操作系統(tǒng)的線程,而是由JVM再提供一層線程的接口抽象,由普通線程調(diào)度,即一個普通的操作系統(tǒng)線程可以調(diào)度成千上萬個虛擬線程。 虛擬線程比普通線程的消耗要小得多得多,在內(nèi)存足夠的情況下,我們甚至可以創(chuàng)建上百萬的虛擬線程,這在之前(Java19以前)是不可能的。

其實如果有用過akka的朋友們會發(fā)現(xiàn),其實兩者很相似,只不過使用akka是應(yīng)用程序來處理,而虛擬線程是JVM來處理,使用上更簡潔且方便。

SpringBoot使用虛擬線程

下面我們會在SpringBoot中使用虛擬線程,將默認(rèn)的異步線程池和http處理線程池替換為虛擬線程,然后對比虛擬線程和普通線程的性能差異,你會發(fā)現(xiàn)差別就像馬車換高鐵,不是一個時代的東西。

配置

首先我們使用的Java版本是java-20.0.2-oracle,SpringBoot版本是3.1.2。

要在SpringBoot中使用虛擬線程很簡單,增加如下配置即可:

java復(fù)制代碼/**
 * 配置是用于稍后測試,spring.virtual-thread=true是使用虛擬線程,false時還是使用默認(rèn)的普通線程
 */
@Configuration
@ConditionalOnProperty(prefix = "spring", name = "virtual-thread", havingValue = "true")
public class ThreadConfig {

    @Bean
    public AsyncTaskExecutor ApplicationTaskExecutor() {
        return new TaskExecutorAdapter(Executors.newVirtualThreadPerTaskExecutor());
    }

    @Bean
    public TomcatProtocolHandlerCustomizer<?> protocolHandlerCustomizer() {
        return protocolHandler -> {
            protocolHandler.setExecutor(Executors.newVirtualThreadPerTaskExecutor());
        };
    }
}

@Async性能對比

我們寫一個異步service,里面睡眠50ms,模擬MySQL或redis等IO操作:

java復(fù)制代碼@Service
public class AsyncService {

    /**
     * 
     * @param countDownLatch 用于測試
     */
    @Async
    public void doSomething(CountDownLatch countDownLatch) throws InterruptedException {
        Thread.sleep(50);
        countDownLatch.countDown();
    }
}

最后測試類,很簡單,就是循環(huán)調(diào)用這個方法10萬次,計算所有方法執(zhí)行完成的消耗的時間:

java復(fù)制代碼@Test
    public void testAsync() throws InterruptedException {
        long start = System.currentTimeMillis();
        int n = 1000;
        CountDownLatch countDownLatch = new CountDownLatch(n);
        for (int i = 0; i < n; i++) {
            asyncService.doSomething(countDownLatch);
        }
        countDownLatch.awAIt();
        long end = System.currentTimeMillis();
        System.out.println("耗時:" + (end - start) + "ms");
    }

普通線程耗時: 678秒左右,超過10分鐘了

 

虛擬線程耗時: 3.9秒!!

 

朋友們,接近200倍的性能差距!!

HTTP請求性能對比

讓我們再看看http請求的對比,簡單寫個get請求,里面什么也不做,一樣睡50ms,模擬IO操作:

java復(fù)制代碼@RequestMapping("/get")
    public Object get() throws Exception {
        Thread.sleep(50);
        return "ok";
    }

然后我們使用jmeter請求接口,500個并發(fā)線程,運行1萬次,看看效果如何:

普通線程:

 

可以看到最小用時50ms,這個沒毛病,接口里面睡眠了50ms,但是不管是中位數(shù)還是90/95/99線都大于150ms了,這是因為系統(tǒng)線程是一個很昂貴的資源,SpringBoot中tomcat默認(rèn)的最大連接數(shù)應(yīng)該是200,在連接池的線程被耗盡后,這200個線程在那干等50ms結(jié)束,而剩下的請求也只能等待,無法進(jìn)行其它的操作。下面再看下虛擬線程的表現(xiàn):

虛擬線程耗時:

 

可以看到即使是最大耗時,也保持在100ms以下,即線程等待時間顯著的減少,虛擬線程更好的利用了系統(tǒng)資源。

總結(jié)

從上面的性能對比來看,虛擬線程在性能方面有明顯的優(yōu)勢,但是要注意的是,我們上面的測試都是讓線程等待了50ms,這是模擬什么場景? 沒錯,是IO密集型場景,即線程大部分時間是在等待IO,這樣虛擬線程才可以發(fā)揮出它的優(yōu)勢,如果是CPU密集型場景,那么可能效果并不大。 不過我們目前大部分的應(yīng)用都是IO密集型應(yīng)用較多,比如典型的WEB應(yīng)用,大量的時間在等待網(wǎng)絡(luò)IO(DB、緩存、HTTP等等),使用虛擬線程的效果還是非常明顯的。

最后:大部分的公司可能還在用Java8,但是我想說的是,是時候升級了,跟上時代的腳步吧,朋友們!

分享到:
標(biāo)簽:線程 虛擬
用戶無頭像

網(wǎng)友整理

注冊時間:

網(wǎng)站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨大挑戰(zhàn)2018-06-03

數(shù)獨一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運動步數(shù)有氧達(dá)人2018-06-03

記錄運動步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績評定2018-06-03

通用課目體育訓(xùn)練成績評定