JAVA线程并发数量控制_并发工具类(三)控制并发线程的数量Semphore

更新时间:2023-06-14 03:56:28 阅读: 评论:0

JAVA线程并发数量控制_并发⼯具类(三)控制并发线程的数
量Semphore
前⾔
JDK中为了处理线程之间的同步问题,除了提供锁机制之外,还提供了⼏个⾮常有⽤的并发⼯具类:CountDownLatch、CyclicBarrier、Semphore、Exchanger、Phar;
医用水蛭CountDownLatch、CyclicBarrier、Semphore、Phar 这四个⼯具类提供⼀种并发流程的控制⼿段;⽽Exchanger⼯具类则提供了在线程之间交换数据的⼀种⼿段。
简介
Semaphore(信号量)是⽤来控制同时访问特定资源的线程数量,它通过协调各个线程,以保证合理的使⽤公共资源。很多年以来,我都觉得从字⾯上很难理解Semaphore所表达的含义,只能把它⽐作是控制流量的红绿灯,⽐如XX马路要限制流量,只允许同时有⼀百辆车在这条路上⾏使,其他的都必须在路⼝等待,所以前⼀百辆车会看到绿灯,可以开进这条马路,后⾯的车会看到红灯,不能驶⼊XX马路,但是如果前⼀百辆中有五辆车已经离开了XX马路,那么后⾯就允许有5辆车驶⼊马路,这个例⼦⾥说的车就是线程,驶⼊马路就表⽰线程在执⾏,离开马路就表⽰线程执⾏完成,看见红灯就表⽰线程被阻塞,不
能执⾏。
应⽤场景
Semaphore可以⽤于做流量控制,特别公⽤资源有限的应⽤场景,⽐如数据库连接。假如有⼀个需求,要读取⼏万个⽂件的数据,因为都是IO密集型任务,我们可以启动⼏⼗个线程并发的读取,但是如果读到内存后,还需要存储到数据库中,⽽数据库的连接数只有10个,这时我们必须控制只有⼗个线程同时获取数据库连接保存数据,否则会报错⽆法获取数据库连接。这个时候,我们就可以使⽤Semaphore来做流控,代码如下:
public class SemaphoreTest {
private static final int THREAD_COUNT = 30;
诚惶诚恐造句private static ExecutorService threadPool = Executors
.newFixedThreadPool(THREAD_COUNT);
private static Semaphore s = new Semaphore(10);
public static void main(String[] args) {
for (int i = 0; i < THREAD_COUNT; i++) {
@Override
public void run() {
try {
s.acquire();
System.out.println("save data");
} catch (InterruptedException e) {
}
}
});
}
threadPool.shutdown();
}
}
在代码中,虽然有30个线程在执⾏,但是只允许10个并发的执⾏。Semaphore的构造⽅法Semaphore(int permits) 接受⼀个整型的数字,表⽰可⽤的许可证数量。Semaphore(10)表⽰允许10个线程获取许可证,也就是最⼤并发数是10。Semaphore的⽤法也很简单,⾸先线程使⽤Semaphore的acquire()获取⼀个许可证,使⽤完之后调⽤relea()归还许可证。还可以⽤tryAcquire()⽅法尝试获取许可证。
Semphore的⽅法摘要
1、获取许可
API中提供了多种的⽅式获取锁:
可以获取⼀个、多个许可;
提供阻塞、⾮阻塞、超时的⽅式获取许可;
除了可中断、还提供⼀个⾮中断的⽅式获取锁;
public void acquire() throws InterruptedException
学生日记300字左右从此信号量获取⼀个许可,在提供⼀个许可前⼀直将线程阻塞,否则线程被中断。
public void acquire(int permits) throws InterruptedException
获取多个许可。从此信号量获取给定数⽬的许可,在提供这些许可前⼀直将线程阻塞,或者线程已被中断。
public void acquireUninterruptibly()
从此信号量中获取许可,在有可⽤的许可前将其阻塞。不可中断。
public void acquireUninterruptibly(int permits)
获取多个许可。从此信号量获取给定数⽬的许可,在提供这些许可前⼀直将线程阻塞。不可中断。
小学一年级英语
public boolean tryAcquire()
白掌花
仅在调⽤时此信号量存在⼀个可⽤许可,才从信号量获取许可。⾮阻塞的⽅式尝试获取许可。
public boolean tryAcquire(int permits)
仅在调⽤时此信号量中有给定数⽬的许可时,才从此信号量中获取这些许可。
public boolean tryAcquire(int permits, long timeout, TimeUnit unit) throws InterruptedException
如果在给定的等待时间内此信号量有可⽤的所有许可,并且当前线程未被中断,则从此信号量获取给定数⽬的许可。超时等待获取许可
public boolean tryAcquire(long timeout, TimeUnit unit) throws InterruptedException
如果在给定的等待时间内,此信号量有可⽤的许可并且当前线程未被中断,则从此信号量获取⼀个许可。
2、许可的释放
public void relea( ):
释放⼀个许可,将其返回给信号量。
public void relea(int permits)
释放给定数⽬的许可,将其返回到信号量。
3、提供的监控⽅法
public int availablePermits( )
返回此信号量中当前可⽤的许可数
public int drainPermits()
获取并返回⽴即可⽤的所有许可
public final int getQueueLength()
返回正在等待获取的线程的估计数⽬。该值仅是估计的数字,因为在此⽅法遍历内部数据结构的同时,线程的数⽬可能动态地变化。此⽅法⽤于监视系统状态,不⽤于同步控制。
public final boolean hasQueuedThreads()
查询是否有线程正在等待获取。
public boolean isFair()
如果此信号量的公平设置为 true,则返回 true。
protected ⽅法:
protected CollectiongetQueuedThreads( )
返回⼀个 collection,包含可能等待获取的线程。因为在构造此结果的同时实际的线程 t 可能动态地变化,所以返回的 collection 仅是尽⼒的估计值。所返回 collection 中的元素没有特定的顺序。
protected void reducePermits(int reduction)
根据指定的缩减量减⼩可⽤许可的数⽬。此⽅法在使⽤信号量来跟踪那些变为不可⽤资源的⼦类中很有⽤
@ Example 获取、释放多个许可
try {
微信字体怎么改
Semaphore maphore = new Semaphore(5);
//获取⼀个许可
maphore.acquire();
//⼀次性获取4个许可
maphore.acquire(4);
System.out.println("Semaphore 剩下的许可数量:"+maphore.availablePermits());
资产评估师报考条件//⼀次性释放5个许可
System.out.println("Semaphore 剩下的许可数量:"+maphore.availablePermits());
//再释放5个许可
怎么算胎儿的体重System.out.println("Semaphore 剩下的许可数量:"+maphore.availablePermits());
} catch (InterruptedException e) {
e.printStackTrace();
运⾏结果:
Semaphore 剩下的许可数量:0
Semaphore 剩下的许可数量:5
Semaphore 剩下的许可数量:10
从上⾯的运⾏结果可以看出,构造⽅法的 new Semaphore(5)中参数5并不是最终的许可数量,可以通过relea()⽅法增加许可数量。⽂献:
《java并发编程的艺术》

本文发布于:2023-06-14 03:56:28,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/82/949704.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:线程   获取   信号量   并发   数据库   阻塞   数量   控制
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图