1.概述
Semaphore 信号量,相当于一个计数器,通常用来限制线程的数量。 每个线程操作前会先获取一个许可证,逻辑处理完成之后就归还这个许可证。
通俗的解释:相当于一个停车场,有10个停车位,进来一个车,占一个停车位,停满了,再有车进来,就要在门口等待, 等出去了一个车,就可以再进来一个车。
2.使用
public class SemaphoreTest {// 定义10个线程private static int THREAD_COUNT = 10;public static void main(String[] args) {ExecutorService executorService = Executors.newFixedThreadPool(THREAD_COUNT);//指定最多只能有五个线程同时执行Semaphore semaphore = new Semaphore(5);for (int i = 0; i < 10; i++) {final int no = i;executorService.execute(new Runnable() {@Overridepublic void run() {try {//获得许可,如果当前没有可用的许可证,则该线程将被阻塞,直到有可用的许可证为止semaphore.acquire();System.out.println("线程名称: " + Thread.currentThread().getName() + "," + no + "获得许可,时间" + LocalDateTime.now());//模拟车辆通行耗时Thread.sleep(2000);//释放许可semaphore.release();} catch (InterruptedException e) {e.printStackTrace();}}});}executorService.shutdown();}}
3.运行结果:
只能有5个线程同时运行。另外5个被堵塞了。
4.原理分析
4.1 构造方法
4.2 获取许可证
semaphore.acquire()
4.3 可中断的共享锁:doAcquireSharedInterruptibly
4.4 公平跟非公平锁的区别
AQS 的 hasQueuedPredecessors()
4.5 hasQueuedPredecessors
通过 #hasQueuedPredecessors() 方法,判断该线程是否位于 CLH 队列的列头,从而实现公平锁。