日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

提升系統吞吐量,詳解JDK21虛擬線程,炸裂

來源: 責編: 時間:2024-06-06 17:36:22 215觀看
導讀環境:JDK211. 虛擬線程簡介虛擬線程是輕量級的線程,可以減少編寫、維護和調試高吞吐量并發應用程序的工作量。線程是可以調度的最小處理單元。它與其他類似單元并發運行,而且在很大程度上是獨立運行的。它是java.lang.Th

環境:JDK21PYg28資訊網——每日最新資訊28at.com

1. 虛擬線程簡介

虛擬線程是輕量級的線程,可以減少編寫、維護和調試高吞吐量并發應用程序的工作量。線程是可以調度的最小處理單元。它與其他類似單元并發運行,而且在很大程度上是獨立運行的。它是java.lang.Thread的一個實例。線程有兩種,平臺線程和虛擬線程。PYg28資訊網——每日最新資訊28at.com

2. 什么是平臺線程

平臺線程被實現為操作系統(OS)線程的薄包裝器。平臺線程在其底層操作系統線程上運行Java代碼,平臺線程在平臺線程的整個生命周期中捕獲其操作系統線程。因此,可用平臺線程的數量受限于操作系統線程的數量。PYg28資訊網——每日最新資訊28at.com

平臺線程通常有一個比較大的線程堆棧和由操作系統維護的其他資源。它們適用于運行所有類型的任務,但可能是有限的資源。PYg28資訊網——每日最新資訊28at.com

3. 什么是虛擬線程

與平臺線程一樣,虛擬線程也是java.lang.thread的一個實例。然而,虛擬線程并沒有綁定到特定的操作系統線程。虛擬線程仍然在操作系統線程上運行代碼。但是,當虛擬線程中運行的代碼調用阻塞I/O操作時,Java運行時會掛起虛擬線程,直到可以恢復為止。與掛起的虛擬線程相關聯的OS線程現在可以自由地執行其他虛擬線程的操作。PYg28資訊網——每日最新資訊28at.com

虛擬線程的實現方式與虛擬內存類似。為了模擬大量內存,操作系統將大量虛擬地址空間映射到有限的RAM。同樣,為了模擬大量線程,Java運行時將大量虛擬線程映射到少量操作系統線程。PYg28資訊網——每日最新資訊28at.com

與平臺線程不同,虛擬線程通常有一個淺調用堆棧,只執行一個HTTP客戶端調用或一個JDBC查詢。盡管虛擬線程支持線程本地變量和可繼承的線程本地變量,但應該仔細考慮使用它們,因為單個JVM可能支持數百萬個虛擬線程。PYg28資訊網——每日最新資訊28at.com

虛擬線程適用于運行大部分時間被阻塞的任務,這些任務通常等待I/O操作完成。然而,它們并不適用于長時間運行的CPU密集型操作。PYg28資訊網——每日最新資訊28at.com

4. 為什么使用虛擬線程

在高吞吐量并發應用程序中使用虛擬線程,尤其是那些由大量并發任務組成、花費大量時間等待的應用程序。服務器應用程序是高吞吐量應用程序的示例,因為它們通常處理許多執行阻塞I/O操作(如獲取資源)的客戶端請求。PYg28資訊網——每日最新資訊28at.com

虛擬線程不是更快的線程;它們運行代碼的速度并不比平臺線程快。它們的存在是為了提供規模(更高的吞吐量),而不是速度(更低的延遲)。PYg28資訊網——每日最新資訊28at.com

5. 創建虛擬線程

Thread和Thread.Builder APIs提供了創建平臺線程和虛擬線程的方法。java.util.concurrent.Executors類還定義了創建ExecutorService的方法,該方法為每個任務啟動一個新的虛擬線程。PYg28資訊網——每日最新資訊28at.com

5.1 Thread & Thread.Builder創建虛擬線程

調用Thread.ofVirtual()方法創建一個Thread.Builder實例,用于創建虛擬線程。如下示例:PYg28資訊網——每日最新資訊28at.com

Thread t= Thread.ofVirtual().start(() -> System.out.println("Hello")) ;t.join() ;

Thread.Builder接口允許創建具有公共線程屬性(如線程名稱)的線程。Thread.Builder.OfPlatform子接口創建平臺線程,而Thread.Builder.OfVirtual創建虛擬線程。PYg28資訊網——每日最新資訊28at.com

下面的示例使用Thread.Builder接口創建一個名為T-VM的虛擬線程,如下示例:PYg28資訊網——每日最新資訊28at.com

Thread.Builder builder = Thread.ofVirtual().name("T-VM") ;Runnable task = () -> {  System.out.println("執行任務") ;} ;Thread t = builder.start(task) ;System.err.printf("線程名稱: %s%n", t.getName()) ;t.join() ;

輸出結果:PYg28資訊網——每日最新資訊28at.com

執行任務線程名稱T-VM

下面的示例創建并啟動兩個具有Thread.Builder的虛擬線程:PYg28資訊網——每日最新資訊28at.com

Thread.Builder builder = Thread.ofVirtual().name("vm - worker - ", 0);Runnable task = () -> {  System.out.printf("線程ID: %d%n", Thread.currentThread().threadId());} ;// 線程 "vm - worker - 0"Thread t1 = builder.start(task) ;   t1.join();System.out.println(t1.getName() + " terminated") ;// 線程 "vm - worker - 1"Thread t2 = builder.start(task) ;   t2.join() ;  System.out.println(t2.getName() + " terminated") ;

輸出結果:PYg28資訊網——每日最新資訊28at.com

線程ID: 21vm - worker - 0 terminated線程ID: 24vm - worker - 1 terminated

以上是通過Thread.Builder創建虛擬線程的簡單示例。PYg28資訊網——每日最新資訊28at.com

5.2 Executors創建虛擬線程

Executors允許將線程管理和創建與應用程序的其余部分分離。PYg28資訊網——每日最新資訊28at.com

ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor() ;// submit Runnable任務Future<?> future = executor.submit(() -> System.out.println("Running thread")) ;future.get() ;System.out.println("Task completed") ;

上面示例每當調用ExecutorService.submit(Runnable)時,都會創建一個新的虛擬線程并開始運行該任務。PYg28資訊網——每日最新資訊28at.com

6. 虛擬線程調度

操作系統在平臺線程運行時進行調度。然而,Java運行時會在虛擬線程運行時進行調度。當Java運行時調度虛擬線程時,它將虛擬線程分配或掛載到平臺線程上,然后操作系統像往常一樣調度該平臺線程。這個平臺線程稱為載體(carrier)。運行一些代碼后,虛擬線程可以從它的載體卸載。這通常發生在虛擬線程執行阻塞I/O操作時。當一個虛擬線程從其宿主中卸載后,宿主就處于空閑狀態,這意味著Java運行時調度器可以在其上分配另一個虛擬線程。PYg28資訊網——每日最新資訊28at.com

虛擬線程被綁定到其宿主(平臺線程)時,在阻塞操作期間無法將其卸載。虛擬線程在以下情況下會被綁定:PYg28資訊網——每日最新資訊28at.com

  • 虛擬線程在同步塊或方法內運行代碼
  • 虛擬線程運行本機方法或外部函數

7. 虛擬線程應用指南

虛擬線程是由Java運行時而不是操作系統實現的Java線程。虛擬線程和傳統線程(平臺線程)的主要區別在于,可以很容易地在同一個Java進程中運行大量甚至數百萬個活動的虛擬線程。正是它們的數量賦予了虛擬線程強大的能力,通過允許服務器并發處理更多請求,它們可以更高效地運行以"thread-per-request"風格編寫的服務器應用程序,從而提高吞吐量,減少硬件浪費。PYg28資訊網——每日最新資訊28at.com

虛擬線程可以顯著提高以thread-per-request風格編寫的服務器的吞吐量,而不是延遲。在這種風格中,服務器在整個持續時間內使用一個線程來處理每個傳入的請求。它至少占用一個線程,因為在處理單個請求時,你可能希望使用更多線程并發地執行某些任務。PYg28資訊網——每日最新資訊28at.com

阻塞平臺線程的代價是昂貴的,因為它會占用線程——這是一種相對稀缺的資源——而線程并沒有做很多有意義的工作。因為虛擬線程可能很多,所以阻塞它們是廉價的,也是值得鼓勵的。因此,應該使用簡單的同步風格并使用阻塞I/O API編寫代碼。PYg28資訊網——每日最新資訊28at.com

如下代碼以非阻塞異步風格編寫,不會從虛擬線程中獲得太多好處。PYg28資訊網——每日最新資訊28at.com

HttpClient client = ... ;Executor pool = Executors.newVirtualThreadPerTaskExecutor() ;CompletableFuture.supplyAsync(() -> {  HttpRequest request = HttpRequest.newBuilder(URI.create("http://localhost:8088/users/info")).build() ;  BodyHandler<String> bodyHandler = ... ;  try {    return client.send(request , bodyHandler) ;  }}, pool).thenCompose(url -> getBodyAsync(url, HttpResponse.BodyHandlers.ofString())).thenApply(info::findImage).thenAccept(this::process).exceptionally(t -> { t.printStackTrace(); return null; });

相反,以下代碼以同步風格編寫,并使用簡單的阻塞IO,將受益匪淺:PYg28資訊網——每日最新資訊28at.com

try {   String page = getBody(info.getUrl(), HttpResponse.BodyHandlers.ofString());   String imageUrl = info.findImage(page);   byte[] data = getBody(imageUrl, HttpResponse.BodyHandlers.ofByteArray());      info.setImageData(data);   process(info);}

8. 不要池化虛擬線程

關于虛擬線程最難理解的是,雖然它們與平臺線程具有相同的行為,但它們不應該表示相同的程序概念。PYg28資訊網——每日最新資訊28at.com

平臺線程很少,因此是一種寶貴的資源。寶貴的資源需要管理,管理平臺線程的最常見方法是使用線程池。接下來你需要回答的問題是,線程池中應該有多少個線程?PYg28資訊網——每日最新資訊28at.com

但是虛擬線程是很多的,因此每個線程不應該代表某種共享的、池化的資源,而應該代表一個任務。PYg28資訊網——每日最新資訊28at.com

將n個平臺線程轉換為n個虛擬線程幾乎沒有好處;相反,需要轉換的是任務。PYg28資訊網——每日最新資訊28at.com

為了將每個應用任務表示為一個線程,不要像下面的例子那樣使用共享線程池:PYg28資訊網——每日最新資訊28at.com

Future<ResultA> f1 = sharedThreadPoolExecutor.submit(task1);Future<ResultB> f2 = sharedThreadPoolExecutor.submit(task2);// ... use futures

相反,使用虛擬線程PYg28資訊網——每日最新資訊28at.com

try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {   Future<ResultA> f1 = executor.submit(task1);   Future<ResultB> f2 = executor.submit(task2);   // ... use futures}

上面的代碼仍然使用ExecutorService,但從Executors.newVirtualThreadPerTaskExecutor()返回的代碼沒有使用線程池。相反,它為每個提交的任務創建一個新的虛擬線程。PYg28資訊網——每日最新資訊28at.com

此外,ExecutorService本身是輕量級的,我們可以像創建任何簡單對象一樣創建一個新的對象。這使得我們可以依賴新添加的ExecutorService#close方法和try-with-resources構造。close方法會在try塊結束時隱式調用,它會自動等待所有提交給ExecutorService的任務(即由ExecutorService生成的所有虛擬線程)結束。PYg28資訊網——每日最新資訊28at.com

對于扇出場景來說,這是一個特別有用的模式,在這種場景中,同時執行多個對不同服務調用,如下面的示例所示:PYg28資訊網——每日最新資訊28at.com

void handle() throws Exception {  URL url1 = URI.create("http://www.pack.com").toURL() ;  URL url2 = URI.create("http://www.akf.com").toURL() ;  try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {    var future1 = executor.submit(() -> fetchURL(url1));    var future2 = executor.submit(() -> fetchURL(url2));    System.out.printf("result1: %s, result2: %s%n", future1.get(),future2.get()) ;  }}String fetchURL(URL url) throws IOException {  try (var in = url.openStream()) {    return new String(in.readAllBytes(), StandardCharsets.UTF_8);  }}

你應該創建一個新的虛擬線程,如上所示,即使是小的、短期的并發任務。PYg28資訊網——每日最新資訊28at.com

9. 避免長時間頻繁的Pinning

當前實現虛擬線程的一個限制是,在同步的塊或方法內部執行阻塞操作會導致JDK的虛擬線程調度器阻塞一個操作系統線程,而在同步的塊或方法外部執行阻塞操作則不會。這種情況稱為“Pinning”。如果阻塞操作持續時間長且頻繁,Pinning可能會對服務器的吞吐量產生負面影響。保護短期的操作,例如內存操作,或者使用同步塊或方法的不頻繁操作,應該不會有任何負面影響。PYg28資訊網——每日最新資訊28at.com

對于長時間又頻繁的地方應該使用ReentrantLock替換synchronized 。PYg28資訊網——每日最新資訊28at.com

synchronized(lockObj) {  frequentIO() ;}// 替換為lock.lock();try {  frequentIO() ;} finally {  lock.unlock() ;}


PYg28資訊網——每日最新資訊28at.com

本文鏈接:http://m.www897cc.com/showinfo-26-92454-0.html提升系統吞吐量,詳解JDK21虛擬線程,炸裂

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 強勢問鼎!強力巨彩斬獲 2023 年 LED 顯示屏銷量第一!

下一篇: 代碼中預編譯常見指令用法

標簽:
  • 熱門焦點
Top 日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不
欧美精品在线观看一区二区| 艳女tv在线观看国产一区| 欧美手机在线视频| 国产精品久久久久秋霞鲁丝| 国产精自产拍久久久久久| 红杏aⅴ成人免费视频| 亚洲第一黄网| 亚洲网站在线| 久久成人久久爱| 欧美多人爱爱视频网站| 欧美日韩精品免费观看视频完整 | 欧美老女人xx| 国产九九视频一区二区三区| 亚洲国产精品成人综合| 亚洲一区二区黄| 久久字幕精品一区| 国产精品豆花视频| 伊人狠狠色丁香综合尤物| 一区二区久久| 久久久水蜜桃av免费网站| 欧美日韩国产精品成人| 国产丝袜一区二区| 亚洲日产国产精品| 欧美一区在线视频| 欧美日韩美女在线| 一区二区亚洲欧洲国产日韩| 亚洲婷婷综合久久一本伊一区| 久久久久久免费| 欧美午夜精品| 亚洲国产精品va在线观看黑人 | 久久午夜电影网| 国产精品电影在线观看| 亚洲国产精品va在线观看黑人| 午夜综合激情| 欧美日韩高清在线| 永久久久久久| 篠田优中文在线播放第一区| 欧美激情黄色片| 黑人一区二区三区四区五区| 中国女人久久久| 欧美成人精品激情在线观看| 国产午夜精品久久久| 中文国产成人精品久久一| 欧美成人dvd在线视频| 国产有码在线一区二区视频| 亚洲午夜女主播在线直播| 欧美承认网站| 精品成人一区二区三区| 午夜视频在线观看一区| 欧美色另类天堂2015| 亚洲欧洲综合另类在线| 久久久之久亚州精品露出| 国产精品视频网站| 中文久久精品| 欧美区日韩区| 亚洲精品一区在线观看| 乱中年女人伦av一区二区| 国产色产综合产在线视频| 亚洲尤物在线| 国产精品家庭影院| 一区二区三区欧美在线| 欧美国产视频日韩| 在线免费观看视频一区| 久久精品欧美日韩| 国产日韩在线视频| 午夜日韩av| 国产精品欧美久久| 亚洲综合第一页| 国产精品久久久久久模特 | 久久久久久一区| 国产亚洲a∨片在线观看| 亚洲免费在线| 国产精品素人视频| 亚洲男女毛片无遮挡| 国产精品白丝jk黑袜喷水| 日韩午夜一区| 精品91在线| 国内精品免费在线观看| 亚洲美女精品成人在线视频| 久久中文欧美| 好吊色欧美一区二区三区视频| 西西裸体人体做爰大胆久久久| 国产精品免费久久久久久| 亚洲视频在线观看三级| 欧美日韩一区综合| 正在播放日韩| 欧美四级在线观看| 亚洲专区一二三| 国产精自产拍久久久久久| 亚洲欧美日韩精品综合在线观看| 国产精品毛片在线看| 亚洲综合丁香| 国产婷婷一区二区| 久久久久成人网| 在线观看一区二区精品视频| 久久综合国产精品| 亚洲经典视频在线观看| 欧美伦理a级免费电影| 在线亚洲欧美| 久久久久久亚洲精品杨幂换脸| 久久久久久9| 国产日韩亚洲欧美综合| 欧美一区二区三区免费看| 国产日韩在线看片| 久久精品一区中文字幕| 影音先锋日韩精品| 欧美大片一区| 亚洲视频免费看| 国产欧美日韩一区| 久久亚洲国产精品一区二区| 亚洲狠狠丁香婷婷综合久久久| 欧美精品一区二区三区在线播放| 艳妇臀荡乳欲伦亚洲一区| 国产精品国产自产拍高清av王其 | 亚洲美女视频在线免费观看| 国产精品mv在线观看| 欧美一级理论片| 亚洲春色另类小说| 欧美日韩久久久久久| 小处雏高清一区二区三区 | 亚洲三级观看| 国产精品看片资源| 久久综合久久综合九色| 一本久道久久综合婷婷鲸鱼| 国产日韩欧美精品一区| 免费观看成人鲁鲁鲁鲁鲁视频 | 亚洲欧美日韩爽爽影院| 欧美国产欧美亚洲国产日韩mv天天看完整 | 久久婷婷蜜乳一本欲蜜臀| 亚洲精品孕妇| 国产女主播一区二区| 免费日韩av| 亚洲夜间福利| 在线观看欧美日韩| 欧美午夜电影一区| 久久久一区二区| 亚洲一区二区三区国产| 久久亚洲影院| 亚洲剧情一区二区| 国产精品一区在线观看你懂的| 久久久久久噜噜噜久久久精品| 99re8这里有精品热视频免费| 国产欧美日韩视频| 欧美福利电影网| 欧美一区二区三区久久精品| 91久久精品一区| 国产欧美一区二区精品忘忧草 | 亚洲国产精品一区在线观看不卡| 欧美午夜一区| 蜜桃精品久久久久久久免费影院| 亚洲影音一区| 亚洲国产精品一区二区www在线| 国产精品无人区| 欧美另类69精品久久久久9999| 久久精品夜色噜噜亚洲aⅴ| 中文在线资源观看视频网站免费不卡| 激情视频一区二区| 国产精品一二三| 欧美日韩国产二区| 午夜精品影院| 欧美精品一区二区三区一线天视频| 亚洲精品美女久久7777777| 国产精品久久久久永久免费观看| 免费成年人欧美视频| 午夜日韩激情| 一本色道久久综合亚洲精品高清 | 欧美巨乳在线| 久久久噜噜噜久久| 亚洲资源在线观看| 日韩亚洲在线| 尤物精品国产第一福利三区 | 国产精品二区二区三区| 欧美精品久久久久a| 老牛国产精品一区的观看方式| 欧美一区二区三区精品| 亚洲视频久久| 一区二区三区波多野结衣在线观看| 亚洲黑丝一区二区| 在线免费精品视频| 黑人操亚洲美女惩罚| 国产一区二区三区高清| 国产麻豆日韩欧美久久| 亚洲电影激情视频网站| 开心色5月久久精品| 在线视频亚洲一区| **性色生活片久久毛片| 国产区亚洲区欧美区| 欧美日韩少妇| 欧美精品福利视频| 欧美风情在线观看| 欧美xx视频| 老司机久久99久久精品播放免费| 久久久精品日韩| 久久精品99国产精品| 欧美亚洲自偷自偷| 性欧美大战久久久久久久免费观看 | 欧美一级电影久久| 午夜在线精品| 久久成人免费| 久久久久久九九九九| 久久米奇亚洲| 亚洲黄色高清| 麻豆av一区二区三区久久| 亚洲欧美日韩电影|