Java并发编程之Semaphore信号量

1. 基本原理

  • 许可计数器
    Semaphore 在构造时设定一个许可数量,这个数量表示可以同时访问共享资源的线程数。

    • 如果许可数为 1,Semaphore 就相当于一个互斥锁;
    • 如果许可数大于 1,就可以允许多个线程同时访问。
  • 获取与释放许可

    • 获取许可:线程调用 acquire() 方法时,会尝试从许可计数器中减去一个许可。如果当前没有足够的许可,线程将阻塞,直到有其他线程释放许可。
    • 释放许可:线程使用完共享资源后,必须调用 release() 方法,将许可归还给 Semaphore,使得其他等待线程能够继续获取许可。

2. 使用方法

import java.util.concurrent.Semaphore;

public class SemaphoreExample {
    // 初始化 Semaphore,设置许可数为 3,表示最多允许 3 个线程同时访问共享资源
    private static final Semaphore semaphore = new Semaphore(3);
    private static int sharedResource = 0;

    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            new Thread(new Worker()).start();
        }
    }

    static class Worker implements Runnable {
        @Override
        public void run() {
            try {
                // 获取许可,若没有可用许可,则阻塞等待
                semaphore.acquire();
                System.out.println(Thread.currentThread().getName() + " 获取许可,开始访问资源。");
                // 对共享资源进行操作(例如累加计数器)
                sharedResource++;
                Thread.sleep(2000); // 模拟操作耗时
                System.out.println(Thread.currentThread().getName() + " 释放许可,结束访问资源。");
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            } finally {
                // 释放许可,允许其他线程进入
                semaphore.release();
            }
        }
    }
}

在这个例子中,Semaphore 被初始化为 3,因此最多允许 3 个线程同时访问 sharedResource。当第 4 个线程调用 acquire() 时,它将会阻塞,直到其他线程调用 release() 归还许可。


3. 特性与注意事项

  • 公平性
    Semaphore 支持公平和非公平两种模式。

    • 公平模式:线程获取许可时按照先入先出顺序进行,防止线程饥饿;
    • 非公平模式:线程获取许可时不保证顺序,这通常能提供更高的吞吐量。
      可以通过构造方法的第二个参数来指定是否为公平模式:
    Semaphore semaphore = new Semaphore(3, true); // 公平模式
    
  • 非重入性

  • 资源池管理
    Semaphore 常用于实现对有限资源的访问控制,通过许可的获取和释放来管理资源的并发访问。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值