信号量
Semaphore代表是一组有限资源的使用许可,多个线程通过得到这些许可来同时使用这一组资源。跟线程池一样,可以控制一个过程的并发度。
示例程序
若一个工厂有 5 台机器,但是有 12 个工人,一台机器同时只能被一个工人使用,只有使用完了,其他工人才能继续使用。也就是同时最多只能有5个人在干活(最大并发度为5)。那么我们就可以通过 Semaphore 来实现。
int workerNum = 12; //工人数
Semaphore semaphore = new Semaphore(5); //机器数
for(int i=0; i<workerNum; i++) {
new Thread(new Runnable() {
@Override
public void run() {
try {
semaphore.acquire();
logger.info("工人"+Thread.currentThread().getName()+"占用一个机器在生产");
Thread.sleep(2000);
logger.info("工人"+Thread.currentThread().getName()+"释放出机器");
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
运行结果:
工人Thread-3占用一个机器在生产
工人Thread-2占用一个机器在生产
工人Thread-1占用一个机器在生产
工人Thread-4占用一个机器在生产
工人Thread-5占用一个机器在生产
工人Thread-4释放出机器
工人Thread-3释放出机器
工人Thread-5释放出机器
工人Thread-8占用一个机器在生产
工人Thread-7占用一个机器在生产
工人Thread-1释放出机器
工人Thread-6占用一个机器在生产
工人Thread-2释放出机器
工人Thread-9占用一个机器在生产
工人Thread-11占用一个机器在生产
工人Thread-8释放出机器
工人Thread-10占用一个机器在生产
工人Thread-7释放出机器
工人Thread-12占用一个机器在生产
工人Thread-6释放出机器
工人Thread-9释放出机器
工人Thread-11释放出机器
工人Thread-10释放出机器
工人Thread-12释放出机器
比较一下CountDownLatch, CyclicBarrier, Semaphore这几个多线程协调工具
- CountDownLatch 线程计数器用于某一个线程要等待其他若干个线程执行完任务之后才可以执行的场景,不可复用。
- CyclicBarrier 回环栅栏用于若干个线程要都执行到某一个状态,然后再同时继续往下执行的场景。可以复用。
- Semaphore 信号量有点类似是一组锁。用来控制对一组资源的访问许可。比如用有限个执行许可来控制最大线程并发度。
网友评论