在Java 21中,引入了虛擬線(xiàn)程(Virtual Threads)來(lái)簡(jiǎn)化和增強(qiáng)并發(fā)性,這使得在Java中編程并發(fā)程序更容易、更高效。
虛擬線(xiàn)程,也稱(chēng)為“用戶(hù)模式線(xiàn)程(user-mode threads)”或“纖程(fibers)”。該功能旨在簡(jiǎn)化并發(fā)編程并提供更好的可擴(kuò)展性。虛擬線(xiàn)程是輕量級(jí)的,這意味著它們可以比傳統(tǒng)線(xiàn)程創(chuàng)建更多數(shù)量,并且開(kāi)銷(xiāo)要少得多。這使得在自己的線(xiàn)程中運(yùn)行單獨(dú)任務(wù)或請(qǐng)求變得更加實(shí)用,即使在高吞吐量的程序中也是如此。
#創(chuàng)建和使用虛擬線(xiàn)程
在Java 21中創(chuàng)建和使用虛擬線(xiàn)程有多種方法:
#1. 使用靜態(tài)構(gòu)建器方法
Thread.startVirtualThread
方法將可運(yùn)行對(duì)象作為參數(shù)來(lái)創(chuàng)建,并立即啟動(dòng)虛擬線(xiàn)程,具體如下代碼:
Runnable runnable = () -> {
System.out.println("Hello, www.didispace.com");
};
// 使用靜態(tài)構(gòu)建器方法
Thread virtualThread = Thread.startVirtualThread(runnable);
也可以使用Thread.ofVirtual()
來(lái)創(chuàng)建,這里還可以設(shè)置一些屬性,比如:線(xiàn)程名稱(chēng)。具體如下代碼:
Thread.ofVirtual()
.name("didispace-virtual-thread")
.start(runnable);
#2. 與ExecutorService
結(jié)合使用
從Java 5開(kāi)始,就推薦開(kāi)發(fā)人員使用ExecutorServices
而不是直接使用Thread
類(lèi)了?,F(xiàn)在,Java 21中引入了使用虛擬線(xiàn)程,所以也有了新的ExecutorService
來(lái)適配,看看下面的例子:
Runnable runnable = () -> {
System.out.println("Hello, www.didispace.com");
};
try (ExecutorService executorService = Executors.newVirtualThreadPerTaskExecutor()) {
for (int i = 0; i < 100; i++) {
executorService.submit(runnable);
}
}
上述代碼在try代碼塊中創(chuàng)建了一個(gè)ExecutorServices
,用來(lái)為每個(gè)提交的任務(wù)創(chuàng)建虛擬線(xiàn)程。
#3. 使用虛擬線(xiàn)程工廠
開(kāi)發(fā)者還可以創(chuàng)建一個(gè)生成虛擬線(xiàn)程的工廠來(lái)管理,具體看下面的例子例子:
Runnable runnable = () -> {
System.out.println("Hello, www.didispace.com");
};
ThreadFactory virtualThreadFactory = Thread.ofVirtual()
.name("didispace", 0)
.factory();
Thread factoryThread = virtualThreadFactory.newThread(runnable);
factoryThread.start();
這段代碼創(chuàng)建了一個(gè)虛擬線(xiàn)程工廠,每個(gè)虛擬線(xiàn)程都會(huì)以didispace
為前綴、以數(shù)字結(jié)尾(從0開(kāi)始累加)的名稱(chēng)。
#小結(jié)
上面我們介紹了虛擬線(xiàn)程的創(chuàng)建和使用,而我們大多數(shù)Java開(kāi)發(fā)者都基于Spring來(lái)開(kāi)發(fā)具體業(yè)務(wù)應(yīng)用,所以很多場(chǎng)景下可能都不太涉及手工創(chuàng)建的操作。所以,對(duì)于虛擬線(xiàn)程的概念,你只需要有一個(gè)基本的認(rèn)識(shí)。所以,在文章的最后,做一個(gè)小結(jié),以方便大家理解和記憶:
- 虛擬線(xiàn)程是由JVM管理的輕量級(jí)線(xiàn)程。
- 虛擬線(xiàn)程不需要任何顯式分配或調(diào)度。
- 虛擬線(xiàn)程非常適合I/O密集型任務(wù)或需要大量并行性的任務(wù)。
- 虛擬線(xiàn)程也可以用來(lái)實(shí)現(xiàn)異步操作。
另外,值得注意的是,雖然虛擬線(xiàn)程可以在并發(fā)性和可擴(kuò)展性方面提供顯著的幫助,但它們并不總是適合所有場(chǎng)景。有些需要大量計(jì)算的任務(wù),并不一定在虛擬線(xiàn)程中運(yùn)行更好,因?yàn)樘摂M線(xiàn)程也有上下文切換的開(kāi)。具體情況還是需要通過(guò)測(cè)試評(píng)測(cè),以找到最優(yōu)解。