Java 21 虛擬執行緒如何限流控制吞吐量

發表於2024-02-26

虛擬執行緒(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。第一時間瞭解前沿行業訊息、分享深度技術乾貨、獲取優質學習資源

相關文章