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

虛擬線程在Spring Boot中的應(yīng)用及性能對比

開發(fā) 前端
虛擬線程由Project Loom引入,并在Java 19中作為預覽功能提供,并且在成為官方JDK 21版本的一部分。此外,Spring 6版本集成了這一強大功能,允許開發(fā)者進行嘗試。

環(huán)境:Spring Boot3.2.5

1. 簡介

在本篇文章中,我們將學習如何在Spring Boot應(yīng)用程序中利用虛擬線程的強大功能。

虛擬線程由Project Loom引入,并在Java 19中作為預覽功能提供,并且在成為官方JDK 21版本的一部分。此外,Spring 6版本集成了這一強大功能,允許開發(fā)者進行嘗試。

首先,我們將了解“平臺線程”與“虛擬線程”之間的主要區(qū)別。接下來,我們將從頭開始構(gòu)建一個使用虛擬線程的Spring Boot應(yīng)用程序。最后,我們將創(chuàng)建一個小型測試,以檢查簡單Web應(yīng)用的吞吐量是否有所提升。

虛擬線程 VS. 平臺線程

主要區(qū)別在于,虛擬線程在運行周期內(nèi)不依賴操作系統(tǒng)線程。虛擬線程與硬件解耦,因此稱為 "虛擬"。此外,JVM 提供的抽象層賦予了這種解耦。

在本文中,我們要驗證虛擬線程的運行成本遠低于平臺線程。我們要確認,創(chuàng)建數(shù)百萬個虛擬線程不會出現(xiàn)內(nèi)存不足錯誤(平臺線程容易出現(xiàn)此問題)。

關(guān)于虛擬線程的詳細介紹,可查看下面這篇文章

提升系統(tǒng)吞吐量,詳解JDK21虛擬線程,炸裂

2. 實戰(zhàn)案例

2.1 開啟虛擬線程支持

從 Spring Boot 3.2 開始,如果我們使用 Java 21,啟用虛擬線程非常簡單。我們將 spring.threads.virtual.enabled 屬性設(shè)置為 true,然后就可以開始了:

spring:
  threads:
    virtual:
      enabled: true

理論上,我們不需要做其他任何事情。但是,從普通線程切換到虛擬線程可能會給傳統(tǒng)應(yīng)用程序帶來不可預見的后果。因此,我們必須對應(yīng)用程序進行全面測試。

2.2 驗證虛擬線程

通過上面開啟虛擬線程后,我們通過如下方式是否正確的開啟了虛擬線程。

@GetMapping("name")
public String toThread() {
  return Thread.currentThread().toString() ;
}

這里我們打印當前處理請求的線程名稱,輸出結(jié)果:

圖片圖片

響應(yīng)結(jié)果明確指出我們正在使用虛擬線程處理此網(wǎng)絡(luò)請求。換句話說,Thread.currentThread() 調(diào)用返回了 VirtualThread 類的一個實例。

2.3 性能對比

為了比較性能,我們將使用 JMeter 運行負載測試。這并不是一個完整的性能比較,而是一個起點,我們可以從這個起點出發(fā),用不同的參數(shù)建立更多的測試。

在這個特定場景中,我們將通過Controller接口進行測試,該接口只需讓執(zhí)行進入休眠狀態(tài)一秒鐘,模擬一個復雜的異步任務(wù):

@RestController
@RequestMapping("/load")
public class LoadTestController {


  private static final Logger logger = LoggerFactory.getLogger(LoadTestController.class) ;


  @GetMapping
  public void test() throws InterruptedException {
      logger.info("日志信息...") ;
      // 模擬耗時操作
      Thread.sleep(1000) ;
  }
}

接下來,在JMeter中創(chuàng)建一個線程組,模擬 1000 個并發(fā)用戶在 100 秒內(nèi)訪問 /load 接口:

圖片圖片

在這種情況下,采用這項新功能所帶來的性能提升是顯而易見的。讓我們比較一下不同實現(xiàn)的 "響應(yīng)時間圖"。這是標準線程的響應(yīng)時間圖。我們可以看到,完成一次調(diào)用所需的時間很快就達到了 5000 毫秒:

圖片圖片

這種情況發(fā)生是因為平臺線程是一種有限資源。當所有計劃的和池中的線程都在忙碌時,Spring 應(yīng)用程序只能等待,直到有一個線程空閑下來,才能處理該請求。

接下來,使用虛擬線程進行測試

圖片圖片

生成的圖表顯示,響應(yīng)時間穩(wěn)定在1000毫秒。因此,從資源消耗的角度來看,虛擬線程非常高效,請求發(fā)出后會立即創(chuàng)建并使用它們。

這種性能提升僅在像我們的演示示例這樣的簡單場景中才可能實現(xiàn)。實際上,對于CPU密集型操作,虛擬線程并不合適,因為這類任務(wù)需要極少的阻塞。

下面,我們在通過一個需要CPU大量計算的操作進行測試,測試代碼如下:

// 該示例計算大數(shù)的階乘
@GetMapping("calc")
public String calc() {
  // 取值越大計算耗時就越高
  int number = 20000 ;
  // 開始時間
  long startTime = System.currentTimeMillis();
  System.out.println("開始時間: " + new Date(startTime));
  // 執(zhí)行耗時計算
  factorial(number);
  // 結(jié)束時間
  long endTime = System.currentTimeMillis();
  System.out.println("結(jié)束時間: " + new Date(endTime));
  // 計算總耗時
  long duration = (endTime - startTime);
  return "計算" + number + "! 耗時: " + duration + " 毫秒" ;
}
private static BigInteger factorial(int n) {
  BigInteger result = BigInteger.ONE;
  for (int i = 1; i <= n; i++) {
    result = result.multiply(BigInteger.valueOf(i));
  }
  return result;
}

首先,是平臺線程測試結(jié)果如下:

圖片圖片

圖片

如下,是虛擬線程測試結(jié)果

圖片圖片

圖片

根據(jù)這里的測試結(jié)果,發(fā)現(xiàn)他們的結(jié)果差不多。但虛擬線程似乎更加平穩(wěn)吧。

責任編輯:武曉燕 來源: Spring全家桶實戰(zhàn)案例源碼
相關(guān)推薦

2011-08-25 17:29:40

LUAPHPWEB

2024-01-10 09:59:19

虛擬線程信息

2012-08-06 13:37:35

瀏覽器WindowsUbuntu

2023-11-27 00:46:39

裸機虛擬機

2024-01-31 08:26:44

2013-11-08 10:59:17

Hadoop虛擬化VMware vSph

2014-06-05 10:22:06

Tomcat 7

2012-07-13 10:57:46

Nginxlua

2022-01-10 09:33:59

Firefox 95Chrome 97 Linux

2024-09-30 11:51:07

2020-11-08 14:43:25

Python列表去重編程

2021-01-28 11:17:49

Python爬蟲單線程

2011-12-14 11:38:42

PhoneGapJavaAndroid

2023-11-06 18:37:23

虛擬線程編寫

2024-11-29 12:58:13

2018-03-01 15:20:59

iOS開發(fā)多線程

2017-04-13 15:15:17

Netflix ZuuNginx性能

2022-12-05 17:01:20

MySQL數(shù)據(jù)庫Oracle

2019-12-25 09:53:01

虛擬機技術(shù)固態(tài)硬盤

2024-10-09 11:31:51

點贊
收藏

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