当前位置:首页 > 行业动态 > 正文

java 信号处理

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()方法代替。

0