Java信号量(Semaphore)是Java并发编程中的一个同步辅助类,它主要用于控制同时访问特定资源的线程数量,信号量可以用来实现资源池、限流等功能,在Java中,信号量的使用主要依赖于java.util.concurrent.Semaphore类。
Semaphore的工作原理是:内部维护了一个许可集,许可集是一个非负整数,当一个线程请求一个许可时,如果许可集中有可用的许可,那么将许可分配给该线程,并将许可集减1;如果许可集中没有可用的许可,那么该线程将被阻塞,直到其他线程释放一个许可,当一个线程释放一个许可时,许可集将加1。
下面是一个简单的Java信号量示例:
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Semaphore; public class SemaphoreExample { public static void main(String[] args) { // 创建一个具有3个许可的信号量 Semaphore semaphore = new Semaphore(3); // 创建一个包含5个线程的线程池 ExecutorService executorService = Executors.newFixedThreadPool(5); // 向线程池中提交任务 for (int i = 0; i < 5; i++) { executorService.submit(new Task(semaphore)); } // 关闭线程池 executorService.shutdown(); } } class Task implements Runnable { private Semaphore semaphore; public Task(Semaphore semaphore) { this.semaphore = semaphore; } @Override public void run() { try { // 请求一个许可 semaphore.acquire(); System.out.println(Thread.currentThread().getName() + "获取到许可"); Thread.sleep(2000); // 模拟任务执行时间 System.out.println(Thread.currentThread().getName() + "释放许可"); // 释放一个许可 semaphore.release(); } catch (InterruptedException e) { e.printStackTrace(); } } }
在这个示例中,我们创建了一个具有3个许可的信号量,然后创建了一个包含5个线程的线程池,我们将任务提交给线程池,每个任务在执行时首先尝试获取一个许可,如果获取到许可则执行任务,任务完成后释放许可,由于信号量只有3个许可,因此同一时间最多只能有3个线程执行任务。
除了acquire()和release()方法外,Semaphore还提供了以下方法:
1、Semaphore(int permits):构造一个具有指定许可数的信号量,参数permits表示许可数,必须大于等于0。
2、boolean tryAcquire():尝试获取一个许可,如果获取成功则返回true,否则返回false,与acquire()方法不同的是,tryAcquire()方法在无法获取许可时不会阻塞线程。
3、boolean tryRelease():尝试释放一个许可,如果释放成功则返回true,否则返回false,与release()方法不同的是,tryRelease()方法在无法释放许可时不会抛出异常。
4、int availablePermits():返回当前可用的许可数。
5、int getQueueLength():返回等待获取许可的线程队列的长度,如果队列为空,则返回0。
6、void reducePermits(int reduction):减少信号量的许可数,参数reduction表示要减少的许可数,可以为正数或负数,负数表示增加许可数,调用此方法后,后续调用acquire()和tryAcquire()方法的线程将会被阻塞,注意:此方法可能导致死锁,请谨慎使用。
7、void increasePermits(int increment):增加信号量的许可数,参数increment表示要增加的许可数,可以为正数或负数,负数表示减少许可数,调用此方法后,后续调用acquire()和tryAcquire()方法的线程将不会被阻塞,注意:此方法可能导致死锁,请谨慎使用。
8、void drainPermits():尝试获取所有可用的许可并立即返回这些许可,如果无法获取任何许可,则返回null,此方法通常用于高并发场景下批量处理任务。
9、boolean hasQueuedThreads():判断是否有线程正在等待获取许可,如果有线程正在等待获取许可,则返回true;否则返回false,注意:此方法可能会被废弃,建议使用availablePermits()和getQueueLength()方法代替。
原创文章,作者:酷盾叔,如若转载,请注明出处:https://www.kdun.com/ask/294888.html
本网站发布或转载的文章及图片均来自网络,其原创性以及文中表达的观点和判断不代表本网站。如有问题,请联系客服处理。
发表回复