概念: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