併發 信號量 Semaphore

what:

Semaphore是用來控制同時訪問特定資源的線程數量,他經過協調各個線程,以保證合理的使用公共資源。數據庫

why:

每一個資源所能承受的併發負載是有限的。併發

how:

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

public class SemaphoreTest {
    private static final int THREAD_COUNT=30;
    private static ExecutorService threadPool =Executors.newFixedThreadPool(THREAD_COUNT);
    private static Semaphore s = new Semaphore(10);
    public static void main(String[] args) {
        for (int i = 0; i < THREAD_COUNT; i++) {
            threadPool.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        s.acquire();
                        System.out.println("save data");
                        s.release();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
        threadPool.shutdown();
    }
}

注:以上代碼中,雖然有30個線程在執行,可是隻容許10個併發執行。Semaphore的構造方法Semaphore(int permits)接受一個整型的數字,表示可用的許可證數量。Semaphore(10)表示容許10個線程獲取許可證,也就是最大併發是10。Semaphore的用法也很簡單,首先線程使用Semaphore的acquire()方法獲取一個許可證,若是獲取失敗,則進入阻塞,使用完以後調用release()方法歸還許可證。還能夠用tryAcquire()方法嘗試獲取許可證。ui

相關文章
相關標籤/搜索