Java並發工具類(三):控制並發線程數的Semaphore


作用

Semaphore(信號量)是用來控制同時訪問特定資源的線程數量,它通過協調各個線程,以保證合理的使用公共資源。

簡介

Semaphore也是一個線程同步的輔助類,可以維護當前訪問自身的線程個數,並提供了同步機制。使用Semaphore可以控制同時訪問資源的線程個數,例如,實現一個文件允許的並發訪問數。

主要方法摘要:

  void acquire():從此信號量獲取一個許可,在提供一個許可前翼子將線程阻塞,否則線程被中斷。

  void release():釋放一個許可,將其返回給信號量。

  int availablePermits():返回此信號量中當前可用的許可數。

  boolean hasQueuedThreads():查詢是否有線程正在等待獲取。

應用場景

Semaphore可以用於做流量控制,特別公用資源有限的應用場景,比如數據庫連接。假如有一個需求,要讀取幾萬個文件的數據,因為都是IO密集型任務,我們可以啟動幾十個線程並發的讀取,但是如果讀到內存后,還需要存儲到數據庫中,而數據庫的連接數只有10個,這時我們必須控制只有十個線程同時獲取數據庫連接保存數據,否則會報錯無法獲取數據庫連接。這個時候,我們就可以使用Semaphore來做流控,代碼如下:

 1 public class SemaphoreTest {
 2 
 3     private static final int THREAD_COUNT = 30;
 4 
 5     private static ExecutorService threadPool = Executors
 6             .newFixedThreadPool(THREAD_COUNT);
 7 
 8     private static Semaphore s = new Semaphore(10);
 9 
10     public static void main(String[] args) {
11         for (int i = 0; i < THREAD_COUNT; i++) {
12             threadPool.execute(new Runnable() {
13                 @Override
14                 public void run() {
15                     try {
16                         s.acquire();
17                         System.out.println("save data");
18                         s.release();
19                     } catch (InterruptedException e) {
20                     }
21                 }
22             });
23         }
24 
25         threadPool.shutdown();
26     }
27 }

在代碼中,雖然有30個線程在執行,但是只允許10個並發的執行。Semaphore的構造方法Semaphore(int permits) 接受一個整型的數字,表示可用的許可證數量。Semaphore(10)表示允許10個線程獲取許可證,也就是最大並發數是10。Semaphore的用法也很簡單,首先線程使用Semaphore的acquire()獲取一個許可證,使用完之后調用release()歸還許可證。還可以用tryAcquire()方法嘗試獲取許可證。

其他方法

Semaphore還提供一些其他方法:

  • int availablePermits() :返回此信號量中當前可用的許可證數。
  • int getQueueLength():返回正在等待獲取許可證的線程數。
  • boolean hasQueuedThreads() :是否有線程正在等待獲取許可證。
  • void reducePermits(int reduction) :減少reduction個許可證。是個protected方法。
  • Collection getQueuedThreads() :返回所有等待獲取許可證的線程集合。是個protected方法。

 

參考:《Java並發編程的藝術》


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM