多線程學習(二)控制併發線程數的Semaphore

併發工具類(二)控制併發線程數的Semaphore

簡介

Semaphore(信號量)是用來控制同時訪問特定資源的線程數量,它經過協調各個線程,以保證合理的使用公共資源。不少年以來,我都以爲從字面上很難理解Semaphore所表達的含義,只能把它比做是控制流量的紅綠燈,好比XX馬路要限制流量,只容許同時有一百輛車在這條路上行使,其餘的都必須在路口等待,因此前一百輛車會看到綠燈,能夠開進這條馬路,後面的車會看到紅燈,不能駛入XX馬路,可是若是前一百輛中有五輛車已經離開了XX馬路,那麼後面就容許有5輛車駛入馬路,這個例子裏說的車就是線程,駛入馬路就表示線程在執行,離開馬路就表示線程執行完成,看見紅燈就表示線程被阻塞,不能執行。 數據庫

應用場景

Semaphore能夠用於作流量控制,特別公用資源有限的應用場景,好比數據庫鏈接。假若有一個需求,要讀取幾萬個文件的數據,由於都是IO密集型任務,咱們能夠啓動幾十個線程併發的讀取,可是若是讀到內存後,還須要存儲到數據庫中,而數據庫的鏈接數只有10個,這時咱們必須控制只有十個線程同時獲取數據庫鏈接保存數據,不然會報錯沒法獲取數據庫鏈接。這個時候,咱們就可使用Semaphore來作流控,代碼以下:
併發

01 public class SemaphoreTest {
02  
03     private static final int THREAD_COUNT = 30;
04  
05     private static ExecutorService threadPool = Executors
06             .newFixedThreadPool(THREAD_COUNT);
07  
08     private static Semaphore s = new Semaphore(10);
09  
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()方法嘗試獲取許可證。 ide

其餘方法

Semaphore還提供一些其餘方法: 工具

  • int availablePermits() :返回此信號量中當前可用的許可證數。
  • int getQueueLength():返回正在等待獲取許可證的線程數。
  • boolean hasQueuedThreads() :是否有線程正在等待獲取許可證。
  • void reducePermits(int reduction) :減小reduction個許可證。是個protected方法。
  • Collection getQueuedThreads() :返回全部等待獲取許可證的線程集合。是個protected方法。
相關文章
相關標籤/搜索