概念:java
一個計數信號量,信號量維護了一個許可集。Semaphore 只對可用許可的號碼進行計數,並採起相應的行動。拿到信號量的線程能夠進入代碼,不然就等待。經過acquire()和release()獲取和釋放訪問許可。ide
驗證示例:ui
public class SemaphoreTest { private static int MAX_VALUE = 5; private static List<Integer> list = new LinkedList<Integer>(); private static Map<Integer, Integer> map = new HashMap<Integer, Integer>(); public static void main(String[] args) throws InterruptedException { // TODO Auto-generated method stub /* Semaphore能夠控制某個資源可被同時訪問的個數 * * Semaphore(int permits) * Semaphore(int permits, boolean fair) * * permits 初始許可數,也就是最大訪問線程數 * fair 當設置爲false時,線程獲取許可的順序是無序的,也就是說新線程可能會比等待的老線程會先得到許可; * 當設置爲true時,信號量保證它們調用的順序(即先進先出;FIFO) */ Semaphore semaphore = new Semaphore(MAX_VALUE, true); ExecutorService es = Executors.newCachedThreadPool();//Executor接口擁有execute方法,ExecutorService繼承Executor for(int i=0; i<4*MAX_VALUE; i++){ //內部類訪問成員變量,若局部變量不修改的狀況下能夠省去final關鍵字,since1.8;若改變,編譯器將提示局部變量必須爲final類型 final int index = i; es.execute(new PRunnable(semaphore, index)); } Thread.sleep(300); //退出線程池 es.shutdown(); System.out.println("最後還有"+semaphore.availablePermits()+"個許可可用"); } } class PRunnable implements Runnable{ private final Semaphore semaphore; private int index; public PRunnable(Semaphore semaphore, int index){ this.semaphore = semaphore; this.index = index; } public void getAcquire(){ System.out.println(index+"號車進入"); } public void releaseAcquire(){ System.out.println(index+"號車離開"); } @Override public void run() { try { //acquire() 獲取從這個信號量許可證,阻塞直到有一個可用,或線程被中斷。 semaphore.acquire(); getAcquire(); //release() 釋放一個許可,將可用的許可數增長 1。若是任意線程試圖獲取許可,則選中一個線程並將剛剛釋放的許可給予它。 semaphore.release(); releaseAcquire(); } catch (InterruptedException e) { e.printStackTrace(); } } }
若是屏蔽semaphore.release()語句,則在控制檯只能打印 MAX_VALUE 條記錄,以後線程一直阻塞。this