当前位置 : 主页 > 编程语言 > java >

Java并发编程之Semaphore概念 *

来源:互联网 收集:自由互联 发布时间:2022-07-05
概述 synchronized 和 ReentrantLock 都是一次只允许一个线程访问某个资源,Semaphore(信号量)可以指定多个线程同时访问某个资源。 Semaphore(信号量)是用来控制同时访问特定资源的线程数量

概述

synchronized 和 ReentrantLock 都是一次只允许一个线程访问某个资源,Semaphore(信号量)可以指定多个线程同时访问某个资源。

Semaphore(信号量)是用来控制同时访问特定资源的线程数量,它通过协调各个线程,以保证合理的使用公共资源。
Semaphore经常用于限制获取某种资源的线程数量.
应用场景Semaphore可以用于做流量控制,特别是公用资源有限的应用场景,比如数据库连接。

假如有一个需求,要读取几万个文件的数据,因为都是IO密集型任务,我们可以启动几十个线程并发地读取,但是如果读到内存后,还需要存储到数据库中,而数据库的连接数只有10个,这时我们必须控制只有10个线程同时获取数据库连接保存数据,否则会报错无法获取数据库连接。

这个时候,就可以使用Semaphore来做流量控制,特别是公用资源有限的应用场景,比如数据库连接。。。

Semaphore的构造方法Semaphore(int permits)接受一个整型的数字,表示可用的许可证数量。Semaphore的用法也很简单,首先线程使用Semaphore的acquire()方法获取一个许可证,如果获取不到就进入阻塞状态,直到有一个许可证可以获得然后拿走一个许可证.

使用完之后调用release()方法归还许可证。还可以用tryAcquire()方法尝试获取许可证,每个 release 方法增加一个许可证,这可能会释放一个阻塞的acquire方法
Java并发编程之Semaphore概念 *_数据库连接

可以一次获取和释放多个许可证

当然一次也可以一次拿取和释放多个许可,可以根据业务场景具体去研究.

// 假设有20个线程
semaphore.acquire(5);// 获取5个许可,所以可运行线程数量为20/5=4
test(threadnum);
semaphore.release(5);// 归还5个许可证

尝试获取许可证

tryAcquire方法,该方法如果获取不到许可就立即返回false

公平和非公平

Semaphore 有两种模式,公平模式和非公平模式,建议使用非公平,吞吐量高.

• 公平模式: 调用acquire的顺序就是获取许可证的顺序,遵循FIFO;
• 非公平模式: 抢占式的。

构造:

// 一个参数是非公平模式
public Semaphore(int permits) {
sync = new NonfairSync(permits);
}
//指定是公平模式还是非公平模式,默认非公平模式。
public Semaphore(int permits, boolean fair) {
sync = fair ? new FairSync(permits) : new NonfairSync(permits);
}

其它方法

acquire(): 获取凭证
tryAcquire() 尝试获取凭证
release(): 归还凭证
intavailablePermits():返回此信号量中当前可用的许可证数。
intgetQueueLength():返回正在等待获取许可证的线程数。
booleanhasQueuedThreads():是否有线程正在等待获取许可证。
void reducePermits(int reduction):减少reduction个许可证,是个protected方法。
Collection getQueuedThreads():返回所有等待获取许可证的线程集合,是个protected方法。

代码演示

源码分析参考:


上一篇:Java多线程之CountDownLatch和CyclicBarrier区别 *
下一篇:没有了
网友评论