接下来我将详细讲解Java并发编程中Semaphore工具类的使用。
Semaphore介绍
Semaphore是一种计数信号量,它可以用来控制同时访问某个特定资源的线程数量。 对于使用Semaphore的程序来说,如果控制的资源达到上限,请求资源的线程就会被阻塞。
Semaphore可以看做是一种更高级别的锁,它能够限制同时访问共享资源的线程数量。相比于锁,Semaphore能够更好地支持多线程并发访问,可以更细粒度地控制线程的访问顺序。
Semaphore有两个核心方法,acquire和release。其中acquire用于请求资源,如果资源不可用,线程就会被阻塞。release则用于释放资源。初始化Semaphore实例时需要传入资源个数,Semaphore会根据资源个数决定可以同时访问该资源的线程数量。
Semaphore使用示例
下面我们来看两个使用Semaphore的示例。
示例1:实现限流器
Semaphore的一个常见使用场景是实现限流器。限流器可以控制系统的请求量,也能够防止系统被恶意攻击。例如,在一些API接口返回结果前,我们需要控制每秒钟最多请求多少次API,同一个IP不能请求太频繁。
下面是一个实现限流器的示例:
import java.util.concurrent.Semaphore;
public class RateLimiter {
private Semaphore semaphore;
public RateLimiter(int permitsPerSecond) {
// 每秒生成 permitsPerSecond 个令牌
semaphore = new Semaphore(permitsPerSecond);
}
// 请求资源
public void acquire() throws InterruptedException {
semaphore.acquire();
}
// 释放资源
public void release() {
semaphore.release();
}
}
在这个示例中,我们创建了一个RateLimiter类,它封装了Semaphore实例。RateLimiter的构造函数需要输入每秒钟生成令牌的个数。在请求资源时,我们使用Semaphore的acquire方法获取令牌。如果没有令牌可以获取,线程就会被阻塞。在释放资源时,我们使用Semaphore的release方法来释放令牌,该令牌就可以被其他线程获取。
示例2:厕所排队
下面我们来看另一个示例,通过Semaphore来模拟厕所排队的场景。假设有5个人需要使用厕所,但是厕所只有2个位置。通过Semaphore来控制同时进入厕所的人数,实现厕所排队的功能。
import java.util.concurrent.Semaphore;
public class Toilet {
private Semaphore semaphore;
public Toilet(int limit) {
semaphore = new Semaphore(limit);
}
public void use() throws InterruptedException {
semaphore.acquire();
System.out.println(Thread.currentThread().getName() + "进入厕所,剩余位置:" + semaphore.availablePermits());
Thread.sleep(2000); // 使用一段时间
System.out.println(Thread.currentThread().getName() + "离开厕所,剩余位置:" + semaphore.availablePermits());
semaphore.release();
}
}
public class Main {
public static void main(String[] args) {
Toilet toilet = new Toilet(2);
for (int i = 1; i <= 5; i++) {
new Thread(() -> {
try {
toilet.use();
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "User" + i).start();
}
}
}
在这个示例中,我们创建了一个Toilet类,它封装了Semaphore实例,并且有一个use方法,代表使用厕所的过程。在use方法中,我们先使用Semaphore的acquire方法申请进入厕所。如果已经没有位置,线程就会被阻塞。当进入厕所后,我们使用Thread.sleep方法来让使用时间长一些。最后我们使用Semaphore的release方法离开厕所。
在main函数中,我们创建了5个线程来模拟5个人同时排队进入厕所。在创建Toilet实例时,我们限制了厕所的最大容纳人数为2,使用Semaphore来控制同时在厕所内的人数。
结论
通过上面的两个示例,我们发现Semaphore在控制多线程并发访问时非常有用。Semaphore可以限制线程的访问数量,从而保证异步程序的正确性和性能。Semaphore是Java并发编程中非常常用的一种工具类,建议大家掌握。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java并发编程之工具类Semaphore的使用 - Python技术站