java多线程之Semaphore

  • Semaphore(信号量)用于限制线程并发的数量(控制同时访问特定资源的线程数量),通过协调各个线程以保证合理地使用公共资源。

  • Semaphore通过使用计数器来控制对共享资源的访问。 如果计数器大于0,则允许访问。 如果为0,则拒绝访问。 计数器所计数的是允许访问共享资源的许可。 因此,要访问资源,必须从信号量中授予线程许可。
  • 主要方法
    void acquire() :从信号量获取一个许可,如果无可用许可前将一直阻塞等待,获取到后减1

    void acquire(int permits) :获取指定数目的许可,如果无可用许可前也将会一直阻塞等待

    boolean tryAcquire():从信号量尝试获取一个许可,如果无可用许可,直接返回false,不会阻塞

    boolean tryAcquire(int permits): 尝试获取指定数目的许可,如果无可用许可直接返回false

    boolean tryAcquire(int permits, long timeout, TimeUnit unit):
    在指定的时间内尝试从信号量中获取许可,如果在指定的时间内获取成功,返回true,否则返回false

    void release():释放一个许可,别忘了在finally中使用,注意:多次调用该方法,会使信号量的许可数增加,达到动态扩展的效果,如:初始permits为1,调用了两次release,最大许可会改变为2

    int availablePermits(): 获取当前信号量可用的许可

  • public class ThreadSemaphore {
    
        public static void main(String[] args) {
    
            //可以指定最多支持多个资源访问的数量
            Semaphore semaphore = new Semaphore( 5);
            ExecutorService executorService = Executors.newFixedThreadPool(10);
            //线程池模拟登录
            for (int i = 1; i <= 10 ; i++) {
                int j =  i;
                executorService.execute(new Runnable() {
                    @Override
                    public void run() {
                        if(semaphore.tryAcquire()){//从信号量获取一个许可,如果无可用许可,直接返回false,不会阻塞
                            System.out.println("用户"+ j + "登录成功");
                        }else{
                            System.out.println("用户"+ j + "登录失败");
                        }
                    }
                });
            }
            executorService.shutdown();
            System.out.println("当前可用许可证数:"+semaphore.availablePermits());// 获取当前信号量可用的许可
            //此时已经登录了10个用户,再次登录的时候会返回false
            if (semaphore.tryAcquire()){
                System.out.println("登录成功!");
            }else{
                System.out.println("登录失败,当前系统登录用户已满,请稍后再来!");
            }
            //释放一个许可
            semaphore.release();
            System.out.println("一个用户下线了!");
            //再次登录
            if (semaphore.tryAcquire()){
                System.out.println("登录成功!");
            }else{
                System.out.println("系统登录用户已满,登录失败!");
            }
        }
    }

    结果:

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值