Semaphore和ThreadPoolExecutor结合使用时,Semaphore无法控制并发数目?

来源:6-3 J.U.C之AQS-Semaphore

蝙蝠之殇

2018-06-01

老师,我使用课堂的代码进行测试时,Semaphore设置并发200,但是实际结果确发现活动线程数目远远超过了200,这是怎么回事?我是在add方法中休眠了2秒

代码如下:

public class CountExample2 {

   // 请求总数
   public static int clientTotal = 5000;

   // 同时并发执行的线程数
   public static int threadTotal = 200;

   public static AtomicInteger count = new AtomicInteger(0);

   public static void main(String[] args) throws Exception {
       ExecutorService executorService = Executors.newCachedThreadPool();
       final Semaphore semaphore = new Semaphore(threadTotal);
       final CountDownLatch countDownLatch = new CountDownLatch(clientTotal);
       System.out.println("运行前活动线程数目:" + Thread.activeCount());
       for (int i = 0; i < clientTotal; i++) {
           final int flag = i;
           executorService.execute(() -> {
               try {
                   semaphore.acquire();
                   add(flag);
                   semaphore.release();
               } catch (Exception e) {
                   log.error("exception", e);
               }
               countDownLatch.countDown();
           });
       }
       countDownLatch.await();
       executorService.shutdown();
       System.out.println("运行后活动线程数目:" + Thread.activeCount());
       log.info("count:{}", count.get());
   }

   private static void add(int i) {
       System.out.println("线程-" + Thread.currentThread().getId() + " => 开始处理第 " + i + " 个请求,当前活动线程数目:" + Thread.activeCount());
       count.incrementAndGet();
       try {
           Thread.sleep(2000);
       } catch (InterruptedException e) {
           e.printStackTrace();
       }

       // count.getAndIncrement();
   }
}

结果如下:

http://img.mukewang.com/szimg/5b10bd960001b35d06960688.jpg

http://img.mukewang.com/szimg/5b10bdd60001809a07880710.jpg

写回答

1回答

Jimin

2018-06-01

你好,使用log输出日志,那样会带上时间,要根据日志输出的时间去判断。单独这样不能作为根本的判断依据。

0
10
蝙蝠之殇
回复
Jimin
嗯,我知道了,谢谢老师
2018-06-01
共10条回复

Java高并发编程,构建并发知识体系,提升面试成功率

构建完整并发与高并发知识体系,倍增高薪面试成功率!

3923 学习 · 832 问题

查看课程