多线程中Semaphore信号量 的使用

本文深入探讨了JDK并发包中的Semaphore信号量,一种用于控制线程访问特定资源的工具类。Semaphore通过协调线程访问,确保合理利用资源,特别适用于数据库连接等公共资源有限的场景。文章还提供了一个示例,展示了如何使用Semaphore限制并发数据库操作的线程数量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

 

   JDK的并发包中提供了几个非常有用的工具类,这些工具类给我们在业务开发过程中提供了一种并发流程控制的手段。设置并发数

Semaphore也叫信号量,在JDK1.5被引入,可以用来控制同时访问特定资源的线程数量,通过协调各个线程,以保证合理的使用资源。

Semaphore内部维护了一组虚拟的许可,许可的数量可以通过构造函数的参数指定。访问特定资源前,必须使用acquire方法获得许可,如果许可数量为0,该线程则一直阻塞,直到有可用许可。访问资源后,使用release释放许可。Semaphore和ReentrantLock类似,获取许可有公平策略和非公平许可策略,默认情况下使用非公平策略。

应用场景:

Semaphore可以用来做流量分流,特别是对公共资源有限的场景,比如数据库连接。假设有这个的需求,读取几万个文件的数据到数据库中,由于文件读取是IO密集型任务,可以启动几十个线程并发读取,但是数据库连接数只有10个,这时就必须控制最多只有10个线程能够拿到数据库连接进行操作。这个时候,就可以使用Semaphore做流量控制。

public class SemaphoreTest { 

private static final int COUNT = 40; 

private static Executor executor = Executors.newFixedThreadPool(COUNT); 

private static Semaphore semaphore = new Semaphore(10); 

public static void main(String[] args) { 

for (int i=0; i< COUNT; i++) { 

executor.execute(new ThreadTest.Task()); } 

} static class Task implements Runnable { 

@Override

 public void run() { try { 

//读取文件操作 

semaphore.acquire(); 

// 存数据过程 

semaphore.release(); 

} catch (InterruptedException e) { 

e.printStackTrace(); } finally { } } } }

当有多个线程时但是访问的某个资源(数据库)却是比较少的,所以为了节约资源可以引用Semaphore做为资源的一个调度。

里面的方法:

Semaphore(int m),参数代表信号量的总数(即允许的通过量)

Acquire()方法在没有许可的情况下,要获取许可的线程会阻塞,而tryAcquire()方法在没有许可的情况下会立即返回 false

Release()释放一个信号   

drainPermits(),这个方法返回即可所有的许可数目,并将许可置0;后面不允许修改 availablePermits() 返回所有可用的许可数

isFair()该Semaphore是否是公平锁机制

如果要增加减少总许可数可以new Semaphore(int m)来创建

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值