Semaphore用來控制同時訪問資源的線程數量,它通過協調各個線程,以保證合理使用公共資源。特別是公用資源有限的情況下,比如數據庫連接。假如有一個需求,要讀取幾萬個文件的數據,因爲都是IO密集型任務,我們可以啓動幾十個線程併發讀取,但是讀到內存之後,還要存儲到數據庫,而數據庫的連接只有5個,這時候,我們必須控制線程數量爲5同時獲取數據庫連接,否則會報無法獲取數據庫連接。這個時候Semaphore就有用武之地了。
舉個例子:
public class SemaphoreClient {
private static final int THREAD_COUNT = 20;
private static ExecutorService threadPool = Executors.newFixedThreadPool(THREAD_COUNT);
private static Semaphore semaphore = new Semaphore(2);
public static void main(String[] args) {
for (int i = 0; i < THREAD_COUNT; i++) {
final int x = i + 1;
threadPool.execute(new Runnable() {
@Override
public void run() {
try {
semaphore.acquire();
System.out.println("Save Data"+x);
System.out.println("AvailablePermits: "+semaphore.availablePermits());
System.out.println("QueueLength: "+semaphore.getQueueLength());
System.out.println("existsthread waiting: "+semaphore.hasQueuedThreads());
semaphore.release();
} catch(InterruptedException e) {
// TODO Auto-generatedcatch block
e.printStackTrace();
}
}
});
}
threadPool.shutdown();
}
}
上述代碼有20個線程,但是隻允許2個線程。其構造方法Semaphore(int Permits) 需要傳遞一個允許併發的線程數量。線程需要
使用Semaphore.acquire()去獲取一個許可證,使用完之後歸還許可證,還可以tryAcquire()方法嘗試獲取許可證。
availablePermits: 所允許的許可證
getQueueLength: 正在等待獲取許可證的線程數
hasQueuedThreads: 是否有線程正在等待獲取許可證。