Semaphore也叫信號量,在JDK1.5被引入,用來控制同時訪問某個特定資源的操作數量,或者同時執行某個指定操作的數量。還可以用來實現某種資源池,或者對容器施加邊界。
Semaphore內部維護了一組虛擬的許可,許可的數量可以通過構造函數的參數指定。
訪問特定資源前,必須使用acquire方法獲得許可,如果許可數量為0,該線程則一直阻塞,直到有可用許可。
訪問資源后,使用release釋放許可。
Semaphore和ReentrantLock類似,獲取許可有公平策略和非公平許可策略,默認情況下使用非公平策略。
當初始值為1時,可以用作互斥鎖,並具備不可重入的加鎖語義。
Semaphore將AQS的同步狀態用於保存當前可用許可的數量。
實現資源池:
一個固定長度的資源池,當池為空時,請求資源會失敗。
使用Semaphore可以實現當池為空時,請求會阻塞,非空時解除阻塞。
也可以使用Semaphore將任何一種容器變成有界阻塞容器。
1 import java.util.concurrent.ExecutorService; 2 import java.util.concurrent.Executors; 3 import java.util.concurrent.Semaphore; 4 5 6 public class SemaPhore { 7 public static void main(String[] args) { 8 // 線程池 9 ExecutorService exec = Executors.newCachedThreadPool(); 10 // 只能5個線程同時訪問 11 final Semaphore semp = new Semaphore(5); 12 // 模擬20個客戶端訪問 13 for (int index = 0; index < 20; index++) { 14 final int NO = index; 15 Runnable run = new Runnable() { 16 public void run() { 17 try { 18 // 獲取許可 19 semp.acquire(); 20 System.out.println("Accessing: " + NO); 21 Thread.sleep((long) (Math.random() * 6000)); 22 // 訪問完后,釋放 23 semp.release(); 24 //availablePermits()指還剩多少個許可 25 System.out.println("-----------------" + semp.availablePermits()); 26 } catch (InterruptedException e) { 27 e.printStackTrace(); 28 } 29 } 30 }; 31 exec.execute(run); 32 } 33 // 退出線程池 34 exec.shutdown(); 35 } 36 }