虛擬執行緒(Virtual Threads)是 Java 21 所有新特性中最為吸引人的內容,它可以大大來簡化和增強Java應用的併發性。但是,隨著這些變化而來的是如何最好地管理此吞吐量的問題。本文,就讓我們看一下開發人員在使用虛擬執行緒時,應該如何管理吞吐量。
在大多數情況下,開發人員不需要自己建立虛擬執行緒。例如,對於 Web 應用程式,Tomcat 或 Jetty 等底層框架將為每個傳入請求自動生成一個虛擬執行緒。
如果在應用程式內部需要自行呼叫來提供業務併發能力時,我們可以使用Java 21新特性:虛擬執行緒(Virtual Threads)中介紹的方法去建立和使用,比如較為常用的就是Executors.newVirtualThreadPerTaskExecutor()
。
Runnable runnable = () -> {
System.out.println("Hello, www.didispace.com");
};
try (ExecutorService executorService = Executors.newVirtualThreadPerTaskExecutor()) {
for (int i = 0; i < 100; i++) {
executorService.submit(runnable);
}
}
我們可以像上面開啟100個虛擬執行緒來執行任務。那麼問題來了,我們要如何對虛擬執行緒限流控制吞吐量呢?
虛擬執行緒的限流
對於虛擬執行緒併發控制的答案是:訊號量!劃重點:不要池化虛擬執行緒,因為它們不是稀缺資源。所以,對於虛擬執行緒併發控制的最佳方案是使用java.util.concurrent.Semaphore
。
下面的程式碼示例演示瞭如何實現java.util.concurrent.Semaphore
來控制虛擬執行緒的併發數量:
public class SemaphoreExample {
// 定義限流併發的訊號量,這裡設定為:10
private static final Semaphore POOL = new Semaphore(10);
public void callOldService(...) {
try{
POOL.acquire(); // 嘗試透過訊號量獲取執行許可
} catch(InterruptedException e){
// 執行許可獲取失敗的異常處理
}
try {
// 獲取到執行許可,這裡是使用虛擬執行緒執行任務的邏輯
} finally {
// 釋放訊號量
POOL.release();
}
}
}
是不是很簡單呢?今天的分享就到這裡,希望對你有所幫助,更多關於Java新特性的學習可以關注我的免費專欄Java新特性。
擴充套件閱讀
歡迎關注我的公眾號:程式猿DD。第一時間瞭解前沿行業訊息、分享深度技術乾貨、獲取優質學習資源