1、Semaphore是什么
Semaphore(信号量)是用来控制同时访问特定资源的线程数量,它通过协调各个线程,以保证合理的使用公共资源。
2、 使用场景
用于有明确限制访问数量的场景,通常是多线程的限流
(1) 数据库连接池,在数据库连接池面对高于自身连接资源时,限制连接数量,保证连接数过多的情况下项目不会崩溃或者变慢
(2)项目内多个节点间的访问,网络io发生峰值并发时,保证节点的并发数安全不至于崩溃
提示:不适合秒杀等场景
3、常用方法说明
(1)acquire();
作用:获取一个令牌,在获取到令牌、或者被其他线程调用中断之前线程一直处于阻塞状态。
(2)acquire(int permits);
作用:获取一个令牌,在获取到令牌、或者被其他线程调用中断、或超时之前线程一直处于阻塞状态。
(3)acquireUninterruptibly()
作用:获取一个令牌,在获取到令牌之前线程一直处于阻塞状态(忽略中断)。
(4)tryAcquire()
作用:尝试获得令牌,返回获取令牌成功或失败,不阻塞线程。
(5)tryAcquire(long timeout, TimeUnit unit)
作用:尝试获得令牌,在超时时间内循环尝试获取,直到尝试获取成功或超时返回,不阻塞线程。
(6)release()
作用:释放一个令牌,唤醒一个获取令牌不成功的阻塞线程。
(7)hasQueuedThreads()
作用:等待队列里是否还存在等待线程。
(8)getQueueLength()
作用:获取等待队列里阻塞的线程数。
(9)drainPermits()
作用:清空令牌把可用令牌数置为0,返回清空令牌的数量。
4、 基本使用
多个线程同时执行,但是限制同时执行的线程数量为 2 个
结果:
从打印结果可以看出,一次只有两个线程执行 acquire(),只有线程进行 release() 方法后才会有别的线程执行 acquire()。
需要注意的是 Semaphore 只是对资源并发访问的线程数进行监控,并不会保证线程安全。