一:认识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