semaphore基于AQS共享锁。
(1)主要方法:
- new Semaphore(3):创建令牌个数为3;
- .acquire():获取令牌,令牌数量减一;
- .release():释放令牌,令牌数量加一;
- .availablePermits():剩余令牌数量;
(2)阻塞队列:
- 入队:当令牌数量为0时,尝试获取令牌失败,进入等待队列;
- 出队:当有线程释放令牌时,唤醒等待队列中的所有线程,竞争令牌。令牌数量为0,再进入等待队列;
(3)使用示例
public void testSemaphore() {for (int i = 0; i < 10; i++) {new Thread(()->{try {System.out.println("========" + Thread.currentThread().getName() + "来到停车场");if(semaphore.availablePermits() == 0){System.out.println("停车位已满");}semaphore.acquire();System.out.println(Thread.currentThread().getName() + "进入");Thread.sleep(new Random().nextInt(1000));System.out.println(Thread.currentThread().getName() + "离开");semaphore.release();} catch (InterruptedException e) {e.printStackTrace();}},i + "号车").start();}}
(4)图解:
- 当有5个线程尝试获取3个令牌:

- 线程1、2、4获取到令牌,0、3没有获取到进入AQS等待队列:

- 此时,线程4释放令牌,线程0从队列出队,获得令牌:

