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

當(dāng)前位置:首頁(yè) > 科技  > 軟件

聊一聊Java 21,虛擬線程、結(jié)構(gòu)化并發(fā)和作用域值

來源: 責(zé)編: 時(shí)間:2023-09-28 10:08:48 292觀看
導(dǎo)讀如果你仍然認(rèn)為之前的JDK 17沒有太多改變,那么JDK 21需要引起你的注意。因?yàn)镴DK 21引入了一種新型的并發(fā)編程模型。目前在Java中的多線程并發(fā)編程是我們頭痛的另一部分。感覺學(xué)起來很困難,使用起來也很復(fù)雜。但是回頭看

如果你仍然認(rèn)為之前的JDK 17沒有太多改變,那么JDK 21需要引起你的注意。因?yàn)镴DK 21引入了一種新型的并發(fā)編程模型。BvF28資訊網(wǎng)——每日最新資訊28at.com

目前在Java中的多線程并發(fā)編程是我們頭痛的另一部分。感覺學(xué)起來很困難,使用起來也很復(fù)雜。但是回頭看看使用其他語(yǔ)言的朋友,他們根本沒有這種麻煩,比如GoLang,使用起來非常順暢。BvF28資訊網(wǎng)——每日最新資訊28at.com

BvF28資訊網(wǎng)——每日最新資訊28at.com

JDK 21在這個(gè)領(lǐng)域取得了巨大的改進(jìn),使Java并發(fā)編程變得更加簡(jiǎn)單和順暢。更準(zhǔn)確地說,這些改進(jìn)在JDK 19或JDK 20中已經(jīng)存在。BvF28資訊網(wǎng)——每日最新資訊28at.com

BvF28資訊網(wǎng)——每日最新資訊28at.com

1*wtYzgJzJD8rGtysVoIW1cw.pngBvF28資訊網(wǎng)——每日最新資訊28at.com

其中,虛擬線程、作用域值和結(jié)構(gòu)化并發(fā)是多線程并發(fā)編程的一些功能。BvF28資訊網(wǎng)——每日最新資訊28at.com

一、虛擬線程

虛擬線程是基于協(xié)程的線程,類似于其他語(yǔ)言中的協(xié)程,但也有一些區(qū)別。BvF28資訊網(wǎng)——每日最新資訊28at.com

虛擬線程附加在主線程上。如果主線程被銷毀,虛擬線程將不再存在。BvF28資訊網(wǎng)——每日最新資訊28at.com

相似之處:BvF28資訊網(wǎng)——每日最新資訊28at.com

  • 虛擬線程和協(xié)程都很輕量級(jí),它們的創(chuàng)建和銷毀開銷比傳統(tǒng)操作系統(tǒng)線程要小。
  • 虛擬線程和協(xié)程都可以通過掛起和恢復(fù)來在線程之間切換,從而避免了線程上下文切換的開銷。
  • 虛擬線程和協(xié)程都可以以異步和非阻塞的方式處理任務(wù),提高了應(yīng)用程序的性能和響應(yīng)能力。

不同之處:BvF28資訊網(wǎng)——每日最新資訊28at.com

  • 虛擬線程是在JVM級(jí)別實(shí)現(xiàn)的,而協(xié)程是在語(yǔ)言級(jí)別實(shí)現(xiàn)的。因此,虛擬線程的實(shí)現(xiàn)可以與支持JVM的任何語(yǔ)言一起使用,而協(xié)程的實(shí)現(xiàn)需要特定的編程語(yǔ)言支持。
  • 虛擬線程是協(xié)程的基于線程的實(shí)現(xiàn),因此它們可以使用與線程相關(guān)的API,如ThreadLocal、Lock和Semaphore。協(xié)程不依賴于線程,通常需要特定的異步編程框架和API。
  • 虛擬線程的調(diào)度由JVM管理,而協(xié)程的調(diào)度由編程語(yǔ)言或異步編程框架管理。因此,虛擬線程可以更好地與其他線程合作,而協(xié)程更適合處理異步任務(wù)。

總的來說,虛擬線程是一種新的線程類型,可以提高應(yīng)用程序的性能和資源利用率,同時(shí)還可以使用傳統(tǒng)的與線程相關(guān)的API。虛擬線程與協(xié)程有許多相似之處,但也存在一些不同之處。BvF28資訊網(wǎng)——每日最新資訊28at.com

虛擬線程確實(shí)可以使多線程編程更加簡(jiǎn)單和高效。與傳統(tǒng)的操作系統(tǒng)線程相比,創(chuàng)建和銷毀虛擬線程的開銷更小,線程上下文切換的開銷也更小,因此可以大大減少多線程編程中的資源消耗和性能瓶頸。BvF28資訊網(wǎng)——每日最新資訊28at.com

使用虛擬線程,開發(fā)人員可以像編寫傳統(tǒng)線程代碼一樣編寫代碼,而不必?fù)?dān)心線程的數(shù)量和調(diào)度,因?yàn)镴VM會(huì)自動(dòng)管理虛擬線程的數(shù)量和調(diào)度。此外,虛擬線程還支持傳統(tǒng)的與線程相關(guān)的API,如ThreadLocal、Lock和Semaphore,這使得開發(fā)人員更容易將傳統(tǒng)線程代碼遷移到虛擬線程中。BvF28資訊網(wǎng)——每日最新資訊28at.com

虛擬線程的引入使多線程編程更加高效、簡(jiǎn)單和安全,允許開發(fā)人員更多關(guān)注業(yè)務(wù)邏輯,而不必過多關(guān)注底層線程管理。BvF28資訊網(wǎng)——每日最新資訊28at.com

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

結(jié)構(gòu)化并發(fā)是一種旨在通過提供結(jié)構(gòu)化且易于遵循的方法來簡(jiǎn)化并發(fā)編程的編程范例。使用結(jié)構(gòu)化并發(fā),開發(fā)人員可以創(chuàng)建更容易理解和調(diào)試、不容易出現(xiàn)競(jìng)態(tài)條件和其他與并發(fā)相關(guān)的錯(cuò)誤的并發(fā)代碼。在結(jié)構(gòu)化并發(fā)中,所有并發(fā)代碼都被結(jié)構(gòu)化為稱為任務(wù)的明確定義的工作單元。任務(wù)以結(jié)構(gòu)化的方式創(chuàng)建、執(zhí)行和完成,任務(wù)的執(zhí)行始終保證在其父任務(wù)完成之前完成。BvF28資訊網(wǎng)——每日最新資訊28at.com

結(jié)構(gòu)化并發(fā)可以使多線程編程更加簡(jiǎn)單和可靠。在傳統(tǒng)的多線程編程中,線程的啟動(dòng)、執(zhí)行和終止都是由開發(fā)人員手動(dòng)管理的,因此容易出現(xiàn)線程泄漏、死鎖和不正確的異常處理等問題。BvF28資訊網(wǎng)——每日最新資訊28at.com

使用結(jié)構(gòu)化并發(fā),開發(fā)人員可以更自然地組織并發(fā)任務(wù),使任務(wù)之間的依賴關(guān)系更清晰,代碼邏輯更簡(jiǎn)潔。結(jié)構(gòu)化并發(fā)還提供了一些異常處理機(jī)制,以更好地管理并發(fā)任務(wù)中的異常,避免由異常引起的程序崩潰或數(shù)據(jù)不一致。BvF28資訊網(wǎng)——每日最新資訊28at.com

此外,結(jié)構(gòu)化并發(fā)還可以通過限制并發(fā)任務(wù)的數(shù)量和優(yōu)先級(jí)來防止資源BvF28資訊網(wǎng)——每日最新資訊28at.com

競(jìng)爭(zhēng)和饑餓現(xiàn)象。這些特性使得開發(fā)人員能夠更容易地實(shí)現(xiàn)高效且可靠的并發(fā)程序,而不必過多關(guān)注底層線程管理。BvF28資訊網(wǎng)——每日最新資訊28at.com

三、作用域值

作用域值是JDK 20中的一項(xiàng)功能,允許開發(fā)人員創(chuàng)建僅限于特定線程或任務(wù)的作用域值。作用域值類似于線程本地變量,但設(shè)計(jì)用于與虛擬線程和結(jié)構(gòu)化并發(fā)一起使用。它們?cè)试S開發(fā)人員以結(jié)構(gòu)化的方式在不同部分的應(yīng)用程序之間傳遞上下文信息,例如用戶身份驗(yàn)證或請(qǐng)求特定數(shù)據(jù)。BvF28資訊網(wǎng)——每日最新資訊28at.com

四、實(shí)踐

在繼續(xù)以下探索之前,您需要至少下載JDK 19或直接下載JDK 20。截止到2023年9月,JDK 20是官方發(fā)布的最高版本。如果使用JDK 19,您將無法體驗(yàn)到Scoped Values功能。BvF28資訊網(wǎng)——每日最新資訊28at.com

BvF28資訊網(wǎng)——每日最新資訊28at.com

1*GQ22_fxZ-eRKk85BBXuHWQ.pngBvF28資訊網(wǎng)——每日最新資訊28at.com

或者直接下載JDK 21的早期訪問版本。BvF28資訊網(wǎng)——每日最新資訊28at.com

BvF28資訊網(wǎng)——每日最新資訊28at.com

1*0hHWnZaMVfsKlVCLjMJUSg.pngBvF28資訊網(wǎng)——每日最新資訊28at.com

如果您使用的是IDEA,則您的IDEA版本必須至少為2022.3或更高版本,否則不支持這樣的新JDK版本。BvF28資訊網(wǎng)——每日最新資訊28at.com

如果您使用的是JDK 19或JDK 20,您應(yīng)該在項(xiàng)目設(shè)置中將語(yǔ)言級(jí)別設(shè)置為19或20。否則,在編譯時(shí)會(huì)提示您無法使用預(yù)覽版本功能。虛擬線程是預(yù)覽版本的功能。BvF28資訊網(wǎng)——每日最新資訊28at.com

BvF28資訊網(wǎng)——每日最新資訊28at.com

1*6oGVASOHa2kRTtbZ--F7AQ.pngBvF28資訊網(wǎng)——每日最新資訊28at.com

如果您使用的是JDK 21,請(qǐng)將語(yǔ)言級(jí)別設(shè)置為X - 實(shí)驗(yàn)性功能。此外,由于JDK 21不是官方版本,您需要進(jìn)入IDEA設(shè)置(請(qǐng)注意,這是IDEA設(shè)置,而不是項(xiàng)目設(shè)置),并手動(dòng)將項(xiàng)目的目標(biāo)字節(jié)碼版本更改為21。當(dāng)前,最高選項(xiàng)為20,即JDK 20。將其設(shè)置為21后,您可以在JDK 21中使用這些功能。BvF28資訊網(wǎng)——每日最新資訊28at.com

BvF28資訊網(wǎng)——每日最新資訊28at.com

1*8ltpmMzUzE4u5CAGgNvIOg.pngBvF28資訊網(wǎng)——每日最新資訊28at.com

1. 虛擬線程

現(xiàn)在我們?nèi)绾螁?dòng)線程?BvF28資訊網(wǎng)——每日最新資訊28at.com

首先,聲明一個(gè)線程類,實(shí)現(xiàn)Runnable接口,并實(shí)現(xiàn)run方法。BvF28資訊網(wǎng)——每日最新資訊28at.com

public class SimpleThread implements Runnable {    @Override    public void run() {        System.out.println("name:" + Thread.currentThread().getName());        try {            Thread.sleep(1000);        } catch (InterruptedException e) {            throw new RuntimeException(e);        }    }}

然后,您可以使用這個(gè)線程類并啟動(dòng)線程。BvF28資訊網(wǎng)——每日最新資訊28at.com

Thread thread = new Thread(new SimpleThread());thread.start();

擁有虛擬線程后,如何實(shí)現(xiàn)呢?BvF28資訊網(wǎng)——每日最新資訊28at.com

Thread.ofPlatform().name("thread-test").start(new SimpleThread());

以下是使用虛擬線程的幾種方式。BvF28資訊網(wǎng)——每日最新資訊28at.com

(1) 直接啟動(dòng)虛擬線程BvF28資訊網(wǎng)——每日最新資訊28at.com

Thread thread = Thread.startVirtualThread(new SimpleThread());

(2) 使用ofVirtual(),構(gòu)建器模式啟動(dòng)虛擬線程,您可以設(shè)置線程名稱、優(yōu)先級(jí)、異常處理和其他配置BvF28資訊網(wǎng)——每日最新資訊28at.com

Thread.ofVirtual()      .name("thread-test")      .start(new SimpleThread());

或者:BvF28資訊網(wǎng)——每日最新資訊28at.com

Thread thread = Thread.ofVirtual()      .name("thread-test")      .uncaughtExceptionHandler((t, e) -> {          System.out.println(t.getName() + e.getMessage());      })      .unstarted(new SimpleThread());thread.start();

(3) 使用工廠創(chuàng)建線程BvF28資訊網(wǎng)——每日最新資訊28at.com

ThreadFactory factory = Thread.ofVirtual().factory();Thread thread = factory.newThread(new SimpleThread());thread.setName("thread-test");thread.start();

(4) 使用ExecutorsBvF28資訊網(wǎng)——每日最新資訊28at.com

ExecutorService executorService = Executors.newVirtualThreadPerTaskExecutor();Future<?> submit = executorService.submit(new SimpleThread());Object o = submit.get();

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

想象以下情景。假設(shè)您有三個(gè)任務(wù)需要同時(shí)執(zhí)行。只要任何一個(gè)任務(wù)完成并返回結(jié)果,就可以直接使用該結(jié)果,可以停止其他兩個(gè)任務(wù)。例如,一個(gè)天氣服務(wù)通過三個(gè)渠道獲取天氣情況,只要一個(gè)渠道返回即可。BvF28資訊網(wǎng)——每日最新資訊28at.com

在這種情況下,在Java 8下應(yīng)該做什么,當(dāng)然也是可以的。BvF28資訊網(wǎng)——每日最新資訊28at.com

List<Future<?>> futures = executor.invokeAll(tasks);String result = executor.invokeAny(tasks);

使用ExecutorService的invokeAll和invokeAny方法實(shí)現(xiàn),但會(huì)有一些額外的工作。在獲取第一個(gè)結(jié)果后,您需要手動(dòng)關(guān)閉另一個(gè)線程。BvF28資訊網(wǎng)——每日最新資訊28at.com

在JDK 21中,可以使用結(jié)構(gòu)化編程來實(shí)現(xiàn)。BvF28資訊網(wǎng)——每日最新資訊28at.com

ShutdownOnSuccess捕獲第一個(gè)結(jié)果并關(guān)閉任務(wù)范圍以中斷未完成的線程并喚醒調(diào)用線程。BvF28資訊網(wǎng)——每日最新資訊28at.com

一種情況是任何子任務(wù)的結(jié)果都可以直接使用,而無需等待其他未完成任務(wù)的結(jié)果。BvF28資訊網(wǎng)——每日最新資訊28at.com

它定義了獲取第一個(gè)結(jié)果或在所有子任務(wù)失敗時(shí)拋出異常的方法。BvF28資訊網(wǎng)——每日最新資訊28at.com

public static void main(String[] args) throws IOException {    try (var scope = new StructuredTaskScope.ShutdownOnSuccess()) {        Future<String> res1 = scope.fork(() -> runTask(1));        Future<String> res2 = scope.fork(() -> runTask(2));        Future<String> res3 = scope.fork(() -> runTask(3));        scope.join();        System.out.println("scope:" + scope.result());    } catch (ExecutionException | InterruptedException e) {        throw new RuntimeException(e);    }}public static String runTask(int i) throws InterruptedException {    Thread.sleep(1000);    long l = new Random().nextLong();    String s = String.valueOf(l);    System.out.println(i + "task:" + s);    return s;}

ShutdownOnFailureBvF28資訊網(wǎng)——每日最新資訊28at.com

執(zhí)行多個(gè)任務(wù),只要有一個(gè)失敗(發(fā)生異?;蛞l(fā)其他活動(dòng)異常),就停止其他未完成的任務(wù),并使用scope.throwIfFailed來捕獲并拋出異常。BvF28資訊網(wǎng)——每日最新資訊28at.com

如果所有任務(wù)都正常,可以使用Feture.get()或*Feture.resultNow()來獲取結(jié)果。BvF28資訊網(wǎng)——每日最新資訊28at.com

public static void main(String[] args) throws IOException {    try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {        Future<String> res1 = scope.fork(() -> runTaskWithException(1));        Future<String> res2 = scope.fork(() -> runTaskWithException(2));        Future<String> res3 = scope.fork(() -> runTaskWithException(3));        scope.join();        scope.throwIfFailed(Exception::new);        String s = res1.resultNow();        System.out.println(s);        String result = Stream.of(res1, res2, res3)                             .map(Future::resultNow)                             .collect(Collectors.joining());        System.out.println("result:" + result);    } catch (Exception e) {        e.printStackTrace();    }}public static String runTaskWithException(int i) throws InterruptedException {    Thread.sleep(1000);    long l = new Random().nextLong(3);    if (l == 0) {        throw new InterruptedException();    }    String s = String.valueOf(l);    System.out.println(i + "task:" + s);    return s;}

3. 作用域值

我們一定使用過ThreadLocal,它是線程本地變量,只要線程不銷毀,就可以隨時(shí)獲取ThreadLocal中的變量值。作用域值也可以在線程內(nèi)的任何時(shí)候獲取變量,但它有一個(gè)作用域的概念,當(dāng)超出作用域時(shí)將被銷毀。BvF28資訊網(wǎng)——每日最新資訊28at.com

public class ScopedValueExample {    final static ScopedValue<String> LoginUser = ScopedValue.newInstance();    public static void main(String[] args) throws InterruptedException {        ScopedValue.where(LoginUser, "Tom")                   .run(() -> {                       new Service().login();                   });        Thread.sleep(2000);    }    static class Service {        void login() {            System.out.println("user:" + LoginUser.get());        }    }}

上面的示例模擬了用戶登錄過程,使用ScopedValue.newInstance()聲明了一個(gè)ScopedValue,使用ScopedValue.where為ScopedValue設(shè)置了一個(gè)值,并使用run方法執(zhí)行接下來要做的事情,以便在run()內(nèi)部隨時(shí)獲取ScopedValue。在run方法中模擬了service的登錄方法,不需要傳遞參數(shù)LoginUser,直接通過LoginUser.get方法可以直接獲取當(dāng)前登錄用戶的值。BvF28資訊網(wǎng)——每日最新資訊28at.com

BvF28資訊網(wǎng)——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-11874-0.html聊一聊Java 21,虛擬線程、結(jié)構(gòu)化并發(fā)和作用域值

聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。郵件:2376512515@qq.com

上一篇: 一文學(xué)會(huì)隊(duì)列入門:Python數(shù)據(jù)結(jié)構(gòu)與算法

下一篇: 八個(gè)重構(gòu)技巧使得Python代碼更Pythonic

標(biāo)簽:
  • 熱門焦點(diǎn)
  • 帥氣純真少年!日本最帥初中生選美冠軍出爐

    日本第一帥哥初一生選美大賽冠軍現(xiàn)已正式出爐,冠軍是來自千葉縣的宗田悠良。日本一直熱衷于各種選美大賽,從&ldquo;最美JK&rdquo;起到&ldquo;最美女星&r
  • K6:面向開發(fā)人員的現(xiàn)代負(fù)載測(cè)試工具

    K6 是一個(gè)開源負(fù)載測(cè)試工具,可以輕松編寫、運(yùn)行和分析性能測(cè)試。它建立在 Go 和 JavaScript 之上,它被設(shè)計(jì)為功能強(qiáng)大、可擴(kuò)展且易于使用。k6 可用于測(cè)試各種應(yīng)用程序,包括 Web
  • SpringBoot中使用Cache提升接口性能詳解

    環(huán)境:springboot2.3.12.RELEASE + JSR107 + Ehcache + JPASpring 框架從 3.1 開始,對(duì) Spring 應(yīng)用程序提供了透明式添加緩存的支持。和事務(wù)支持一樣,抽象緩存允許一致地使用各
  • 如何通過Python線程池實(shí)現(xiàn)異步編程?

    線程池的概念和基本原理線程池是一種并發(fā)處理機(jī)制,它可以在程序啟動(dòng)時(shí)創(chuàng)建一組線程,并將它們置于等待任務(wù)的狀態(tài)。當(dāng)任務(wù)到達(dá)時(shí),線程池中的某個(gè)線程會(huì)被喚醒并執(zhí)行任務(wù),執(zhí)行完任
  • 2023年,我眼中的字節(jié)跳動(dòng)

    此時(shí)此刻(2023年7月),字節(jié)跳動(dòng)從未上市,也從未公布過任何官方的上市計(jì)劃;但是這并不妨礙它成為中國(guó)最受關(guān)注的互聯(lián)網(wǎng)公司之一。從2016-17年的抖音強(qiáng)勢(shì)崛起,到2018年的&ldquo;頭騰
  • “又被陳思誠(chéng)騙了”

    作者|張思齊 出品|眾面(ID:ZhongMian_ZM)如今的國(guó)產(chǎn)懸疑電影,成了陳思誠(chéng)的天下。最近大爆電影《消失的她》票房突破30億斷層奪魁暑期檔,陳思誠(chéng)再度風(fēng)頭無兩。你可以說陳思誠(chéng)的
  • 認(rèn)真聊聊東方甄選:如何告別低垂的果實(shí)

    來源:山核桃作者:財(cái)經(jīng)無忌爆火一年后,俞敏洪和他的東方甄選依舊是頗受外界關(guān)心的&ldquo;網(wǎng)紅&rdquo;。7月5日至9日,為期5天的東方甄選&ldquo;甘肅行&rdquo;首次在自有App內(nèi)直播,
  • 2299元起!iQOO Pad明晚首銷:性能最強(qiáng)天璣平板

    5月23日,iQOO如期舉行了新品發(fā)布會(huì),除了首發(fā)安卓最強(qiáng)旗艦處理器的iQOO Neo8系列新機(jī)外,還在發(fā)布會(huì)上推出了旗下首款平板電腦——iQOO Pad,其最大的賣點(diǎn)
  • 朋友圈可以修改可見范圍了 蘋果用戶可率先體驗(yàn)

    近日,iOS用戶迎來微信8.0.27正式版更新,除了可更換二維碼背景外,還新增了多項(xiàng)實(shí)用功能。在新版微信中,朋友圈終于可以修改可見范圍,簡(jiǎn)單來說就是已發(fā)布的朋友圈
Top 主站蜘蛛池模板: 资兴市| 合水县| 石泉县| 柘荣县| 青冈县| 宁河县| 格尔木市| 富平县| 桃园市| 河北区| 乳源| 益阳市| 原平市| 罗源县| 安义县| 瑞安市| 阿克苏市| 霍林郭勒市| 夏河县| 阿拉善右旗| 玉树县| 黔西| 林芝县| 巴林左旗| 永康市| 华亭县| 延川县| 鱼台县| 曲阜市| 普陀区| 万源市| 衡阳市| 尚义县| 怀宁县| 泸溪县| 华蓥市| 双柏县| 德钦县| 昌平区| 康乐县| 壶关县|