信号量(Semaphore)是什么,如何使用?

信号量(Semaphore)是 Java java.util.concurrent 包中的一种同步辅助类,用于控制对共享资源的访问。在并发编程中,信号量常用于限制同时访问特定资源的线程数量,避免过多线程同时访问可能导致的资源竞争或性能下降。

使用场景

  1. 限制并发访问:当某个资源(如连接池、数据库等)有限制时,可以使用信号量来控制同时访问该资源的线程数量。
  2. 节流控制:限制请求的处理速率,以防止系统过载。
  3. 多线程协调:在某些情况下,信号量可以用于在多个线程之间进行协调。

基本使用

以下是一个使用信号量的基本示例:

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个线程同时访问
        final Semaphore semaphore = new Semaphore(3);

        // 创建线程池
        ExecutorService executor = Executors.newFixedThreadPool(10);

        for (int i = 0; i < 10; i++) {
            final int threadNumber = i;
            executor.submit(() -> {
                try {
                    // 获取信号量
                    semaphore.acquire();
                    System.out.println("线程 " + threadNumber + " 获得信号量,正在执行...");

                    // 模拟执行任务
                    Thread.sleep(2000);

                    System.out.println("线程 " + threadNumber + " 执行完毕,释放信号量。");
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt(); // 恢复中断状态
                } finally {
                    // 释放信号量
                    semaphore.release();
                }
            });
        }

        executor.shutdown();
    }
}

代码分析

  1. 创建信号量:使用 new Semaphore(3) 创建一个信号量,允许最多 3 个线程同时访问。
  2. 提交任务:使用 ExecutorService 创建线程池并提交 10 个任务。
  3. 获取信号量:在每个线程中,调用 semaphore.acquire() 尝试获取信号量。如果当前信号量的许可数量为 0,线程会被阻塞,直到其他线程释放信号量。
  4. 执行任务:线程获得信号量后,模拟执行某些操作(如休眠 2 秒)。
  5. 释放信号量:执行完成后,无论成功与否,确保在 finally 块中调用 semaphore.release(),以释放信号量,让其他等待线程可以继续执行。

注意事项

  1. 信号量许可证的数量:信号量的许可证数量应该基于实际需要进行设置,以避免过多的线程同时获取许可造成系统资源耗尽。
  2. 捕获 InterruptedException:使用 acquire() 方法时,可能会抛出 InterruptedException,应当妥善处理。
  3. 公平性Semaphore 有一个构造函数可以接受一个布尔参数,指定是否采用公平策略。公平策略保证先请求的线程先获得许可,但可能会影响性能。
Semaphore semaphore = new Semaphore(3, true); // 公平模式

通过合理使用信号量,可以有效地管理多线程对共享资源的访问,避免资源竞争和潜在的性能问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值