信号量 ,就想成是信号灯,超时时间,就想成是 信号灯的时长。 获取一个许可,就好比只有一个车道;多个许可,就是多个车道 许可越多,单位时间通过的车也越多。
semaphore使用场景:常用于仅能提供有限访问的资源(项目中的数据库,连接数最大为20,上层应用的并发数远远大于20,同时对数据库进行操作时,可能出现无法获取数据库连接出现异常。此时可以通过semaphore来控制并发访问个数,semaphore将并发数控制到1时,就和单线程一样了)。
package com.mmall.concurrency.example.aqs; import lombok.extern.slf4j.Slf4j; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Semaphore; @Slf4j public class SemaphoreExample2 { private final static int threadCount = 20; public static void main(String[] args) throws Exception { ExecutorService exec = Executors.newCachedThreadPool(); final Semaphore semaphore = new Semaphore(3); for (int i = 0; i < threadCount; i++) { final int threadNum = i; exec.execute(() -> { try { semaphore.acquire(3); // 获取多个许可 test(threadNum); semaphore.release(3); // 释放多个许可 } catch (Exception e) { log.error("exception", e); } }); } exec.shutdown(); } private static void test(int threadNum) throws Exception { log.info("{}", threadNum); Thread.sleep(1000); } }
分析
我当时看到这应用情景也没理解。后来想了下,应该是这个意思:
new Semaphore(permits:3); 相当于开放了 3 个通道。
acquire(permits:3); 相当于占用了 3 个通道,注意注意:这里指的是一个线程(一辆大车)占用了 3 个通道,如果理解成也是开放了 3 个通道的话,就怎么想都想不明白的。
所以这样的话,你最后一个问题也迎刃而解,释放了 1 个通道的话,其他占用 3 个通道的大车,肯定会被堵住。
所以再假设 acquire(permits:n),Semaphore(permits:m)。
当 n > m 的时候,一个都输不出来,能明白了吗!