一:认识Seamphore
Seamphore信号量主要用来控制同时访问特定资源的线程数量,我们可以把它理解成用来限流用的。
其主要方法如下:
acquire(),获得许可,如果没获取到,会一直等待。
acquire(int permits):获得permits个许可。
tryAcquire(),尝试获得许可。
release():释放许可。
Collection<Thread> getQueuedThreads():返回所有等待获取许可的线程集合。
boolean hasQueuedThreads():是否有线程在等待获取许可。
int availablePermits():返回当前可以的许可证的数量。
int getQueueLength():返回正在等待获取许可的线程数量。
二:举例说明
? 模拟8个线程同时访问某个资源,采用Seamphore来控制并发访问量
public class SemaphoreExample { public static void main(String[] args) { ExecutorService service = Executors.newFixedThreadPool(10); final Semaphore semaphore = new Semaphore(5); final CountDownLatch countDownLatch = new CountDownLatch(1); for (int i = 1; i <= 8; i++) { final int index = i; service.submit(new Runnable() { @Override public void run() { try { semaphore.acquire(); System.out.println("获得许可:" + Thread.currentThread().getName()); //不释放锁,模拟操作 Thread.sleep(1000); System.out.println("释放许可:" + Thread.currentThread().getName()); semaphore.release(); System.out.println("当前允许进入的最大任务数:" + semaphore.availablePermits()); } catch (InterruptedException e) { e.printStackTrace(); } finally{ if(index == 8){ countDownLatch.countDown(); } } } }); } try { System.out.println("main线程等待:" + Thread.currentThread().getName()); countDownLatch.await(); System.out.println("模拟执行完毕....."); service.shutdown(); } catch (InterruptedException e) { e.printStackTrace(); } } }
?可能得运行结果如下:
获得许可:pool-1-thread-1 获得许可:pool-1-thread-3 获得许可:pool-1-thread-2 获得许可:pool-1-thread-4 获得许可:pool-1-thread-5 main线程等待:main 释放许可:pool-1-thread-1 当前允许进入的最大任务数:1 获得许可:pool-1-thread-6 释放许可:pool-1-thread-5 释放许可:pool-1-thread-2 当前允许进入的最大任务数:2 获得许可:pool-1-thread-7 释放许可:pool-1-thread-3 当前允许进入的最大任务数:1 获得许可:pool-1-thread-8 当前允许进入的最大任务数:2 释放许可:pool-1-thread-4 当前允许进入的最大任务数:2 释放许可:pool-1-thread-6 当前允许进入的最大任务数:3 释放许可:pool-1-thread-7 当前允许进入的最大任务数:4 释放许可:pool-1-thread-8 当前允许进入的最大任务数:5 模拟执行完毕.....
? 可以看到,每次最多5个线程并发执行,后面的线程必须等待。
??? ???
原文:http://090508tanjie.iteye.com/blog/2289713