Java并发工具包——Semaphore
回顾
上一期跟大家分享的是CyclicBarrier,不知道大家还记不记得相关的内容。如果忘了可以找时间回顾一下我之前的文章。
简介
Semaphore——直译为信号量。笔者个人可以理解为信号灯,因为它的作用好比是道路上的交通信号灯,车道可以理解为并行执行的线程,那么信号灯变成了可通行的颜色,那么车道上的车就可以并行的行驶了,前面的车开之后,后面的车紧跟着通行即可。
应用场景
其实信号量的应用场景跟之前的两个类也比较类似,都是通过单一实例(单例)来控制多线程的并发问题。
- 实现生产者消费者模型
- 共享资源的控制——连接池等共享资源的控制
例子
一个简单的信号灯例子
构造方法
- Semaphore(int n)——初始化资源数量
- Semaphore(int n, boolean b)——初始化资源数量,跟公平性(等待时间长短排序,长的优先)
常用的方法(默认是操作信号量中的一个资源)
- acquire()——获取资源(如果获取不到资源就会阻塞线程执行)
- release()——释放资源
- acquire(int n)——获取N个资源
- release(int n)——释放N个资源
- tryAcquire()——尝试获取资源,立即返回结果,不阻塞
- tryAcquire(long timeout, TimeUnit unit)——阻塞,并且设定时间内成功获取资源返回true,否则返回false
- tryAcquire(int n)——尝试获取N个资源
- tryAcquire(int n, long timeout, TimeUnit unit)——设定时间内成功获取N个资源true,否则false
实现原理
Semaphore内部类实现了AbstractQueuedSynchronizer这个抽象类,通过CAS的方法来完成原子性操作,感兴趣的小伙伴可以私信交流,后续会有锁的专题,到时候会详细讲到这些。
总结
- CountDownLatch和CyclicBarrier都是实现线程之间的等待,只是关注的地方有些不同。
- CountDownLatch关注于某个等待N个其他线程执行完成后执行
- CyclicBarrier关注于一组线程互相等待,都到达预期的执行点后一起执行
Semaphore更像是锁,用于对共享资源的控制
常见面试问题
- 并发包中用过哪些工具类
- Semaphore是否有使用过
- 常用的方法有哪些,应用场景有哪些
- 这些常用方法怎么实现的