信号量(Semaphore)概念上講, 一個信号量管理許多的許可證 ( permit ) 。 為了通過信号量 , 線程通過調用acquire 請求許可 。 其實沒有實際的許可對象 , 信号量僅維護一個計數 。 許可的數目是固定的, 由此限制了通過的線程數量 。 其他線程可以通過調用 release釋放許可。 而且 , 許可不是二必須由擷取它的線程釋放。 事實上 , 任何線程都可以釋放任意數目的許可 , 這可能會增加許可數目以至于超出初始數目。
Semaphore可以用于做流量控制,特别公用資源有限的應用場景,比如資料庫連接配接。假如有一個需求,要讀取幾萬個檔案的資料,因為都是IO密集型任務,我們可以啟動幾十個線程并發的讀取,但是如果讀到記憶體後,還需要存儲到資料庫中,而資料庫的連接配接數隻有10個,這時我們必須控制隻有十個線程同時擷取資料庫連接配接儲存資料
public class SemaphoreTest {
private static final int THREAD_COUNT = 30;
private static ExecutorService threadPool = Executors.newFixedThreadPool(THREAD_COUNT);
private static Semaphore s = new Semaphore(5);
public static void main(String[] args) {
for (int i = 0; i < THREAD_COUNT; i++) {
final int j = i;
threadPool.execute(new Runnable() {
@Override
public void run() {
try {
//System.out.println(Thread.currentThread().getId() +" start work " + j);
s.acquire();
Thread.sleep(10000);
System.out.println(Thread.currentThread().getId() + " working " + j);
s.release();
System.out.println(Thread.currentThread().getId() +" end work " + j);
} catch (InterruptedException e) {
}
}
});
}
threadPool.shutdown();
}
}