使用Seamphore限制并发请求量(转)

一:认识Seamphore
  Seamphore信号量主要用来控制同时访问特定资源的线程数量,我们可以把它理解成用来限流用的。
  其主要方法如下:
  acquire(),获得许可,如果没获取到,会一直等待。
  acquire(int permits):获得permits个许可。
  tryAcquire(),尝试获得许可。
  release():释放许可。
  Collection<Thread> getQueuedThreads():返回所有等待获取许可的线程集合。
  boolean hasQueuedThreads():是否有线程在等待获取许可。
  int availablePermits():返回当前可以的许可证的数量。
  int getQueueLength():返回正在等待获取许可的线程数量。
二:举例说明
  模拟8个线程同时访问某个资源,采用Seamphore来控制并发访问量

Java代码   收藏代码
  1. public class SemaphoreExample {  
  2.    public static void main(String[] args) {  
  3.        ExecutorService service = Executors.newFixedThreadPool(10);  
  4.        final Semaphore semaphore = new Semaphore(5);  
  5.        final CountDownLatch countDownLatch = new CountDownLatch(1);  
  6.        for (int i = 1; i <= 8; i++) {  
  7.            final int index = i;  
  8.            service.submit(new Runnable() {  
  9.                @Override  
  10.                public void run() {  
  11.                    try {  
  12.                        semaphore.acquire();  
  13.                        System.out.println("获得许可:"  
  14.                                + Thread.currentThread().getName());  
  15.                        //不释放锁,模拟操作  
  16.                        Thread.sleep(1000);  
  17.                        System.out.println("释放许可:"  
  18.                                + Thread.currentThread().getName());  
  19.                        semaphore.release();  
  20.                        System.out.println("当前允许进入的最大任务数:" + semaphore.availablePermits());  
  21.                    } catch (InterruptedException e) {  
  22.                        e.printStackTrace();  
  23.                    } finally{  
  24.                        if(index == 8){  
  25.                            countDownLatch.countDown();  
  26.                        }  
  27.                    }  
  28.                }  
  29.            });  
  30.        }  
  31.        try {  
  32.            System.out.println("main线程等待:" + Thread.currentThread().getName());  
  33.            countDownLatch.await();  
  34.            System.out.println("模拟执行完毕.....");  
  35.            service.shutdown();  
  36.        } catch (InterruptedException e) {  
  37.            e.printStackTrace();  
  38.        }  
  39.    }  

 可能得运行结果如下: 

Java代码   收藏代码
  1. 获得许可:pool-1-thread-1  
  2. 获得许可:pool-1-thread-3  
  3. 获得许可:pool-1-thread-2  
  4. 获得许可:pool-1-thread-4  
  5. 获得许可:pool-1-thread-5  
  6. main线程等待:main  
  7. 释放许可:pool-1-thread-1  
  8. 当前允许进入的最大任务数:1  
  9. 获得许可:pool-1-thread-6  
  10. 释放许可:pool-1-thread-5  
  11. 释放许可:pool-1-thread-2  
  12. 当前允许进入的最大任务数:2  
  13. 获得许可:pool-1-thread-7  
  14. 释放许可:pool-1-thread-3  
  15. 当前允许进入的最大任务数:1  
  16. 获得许可:pool-1-thread-8  
  17. 当前允许进入的最大任务数:2  
  18. 释放许可:pool-1-thread-4  
  19. 当前允许进入的最大任务数:2  
  20. 释放许可:pool-1-thread-6  
  21. 当前允许进入的最大任务数:3  
  22. 释放许可:pool-1-thread-7  
  23. 当前允许进入的最大任务数:4  
  24. 释放许可:pool-1-thread-8  
  25. 当前允许进入的最大任务数:5  
  26. 模拟执行完毕.....  

  可以看到,每次最多5个线程并发执行,后面的线程必须等待。

猜你喜欢

转载自sunbin.iteye.com/blog/2289722