Semaphore

24 篇文章 0 订阅

概念

   Semaphore是java并发包里面的一个工具类,我们限制可以访问某些资源的线程数目就可以使用Semaphore了

   Semaphore:可理解为允许线程执行信号的池子,池子中放入多少个信号就允许多少线程同时执行。

   Semaphore的作用:限制线程并发的数量

注意:的是 Semaphore 只是对资源并发访问的线程数进行监控,并不会保证线程安全

Semaphore使用方法

Semaphore(int permits)
创建具有给定的许可数和非公平的公平设置的 Semaphore。

permits 表示许可线程的数量

Semaphore(int permits, boolean fair)
创建具有给定的许可数和给定的公平设置的 Semaphore。

fair 表示公平性,如果这个设为 true 的话,下次执行的线程会是等待最久的线程

重要方法
release(int permits)
释放给定数目的许可,将其返回到信号量。

方法release(n) 的功能是每调用1次此方法,就动态添加n个许可
acquire()
从此信号量获取一个许可,在提供一个许可前一直将线程阻塞,否则线程被中断。

方法acquire(n) 的功能是每调用1次此方法,就消耗掉n个许可

其他方法:
方法acquireUnnterruptibly()作用是是等待进入acquire() 方法的线程不允许被中断。
方法availablePermits() 返回Semaphore对象中当前可以用的许可数。
方法drainPermits() 获取并返回所有的许可个数,并且将可用的许可重置为0
方法 getQueueLength() 的作用是取得等待的许可的线程个数
方法 hasQueueThreads() 的作用是判断有没有线程在等待这个许可

方法tryAcquire() 的作用是尝试获取1个许可。如果获取不到则返回false,通常与if语句结合使用,其具有无阻塞的特点。无阻塞的特点可以使不至于在同步处于一直持续等待的状态。
方法tryAcquire(n) 的作用是尝试获取n个许可,如果获取不到则返回false
方法tryAcquire(long timeout,TimeUnit unit)的作用是在指定的时间内尝试获取1个许可,如果获取不到则返回false
方法tryAcquire(int permits,long timeout,TimeUnit unit) 的作用是在指定的时间内尝试获取n 个许可,如果获取不到则返回false

 

应用场景

可用于流量控制,限制最大的并发访问数

数据库连接等

 

实列代码(许可2线程的数量):

 //许可2线程的数量
 static Semaphore semaphore = new Semaphore(2,true); // 最大线程数
    public static void main(String[] args) {
        for(int i=0;i<10;i++){
            new Thread(new Runnable() {

                @Override
                public void run() {
                    Semaphoretest();
                }
            }).start();
        }

    }

    public static void Semaphoretest(){
        try {
            //申请一个请求
            semaphore.acquire(); // 如果线程超过设置个,其他线程会阻塞到这来,知道线程执行结束释放许可
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"进来了");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"走了");
        //释放一个请求
        semaphore.release();
    }


}
结果 

Thread-0进来了
Thread-1进来了

Thread-0走了
Thread-2进来了
Thread-1走了
Thread-3进来了
Thread-3走了
Thread-2走了
Thread-4进来了
Thread-5进来了
Thread-5走了
Thread-4走了
Thread-6进来了
Thread-7进来了
Thread-7走了
Thread-6走了
Thread-8进来了
Thread-9进来了
Thread-8走了
Thread-9走了

解释:最大并发2个线程 只有线程进行 release() 方法后才会有别的线程执行 acquire()

实列代码(许可3线程的数量):

 //许可3线程的数量
 static Semaphore semaphore = new Semaphore(3,true); // 最大线程数
    public static void main(String[] args) {
        for(int i=0;i<10;i++){
            new Thread(new Runnable() {

                @Override
                public void run() {
                    Semaphoretest();
                }
            }).start();
        }

    }

    public static void Semaphoretest(){
        try {
            //申请一个请求
            semaphore.acquire(); // 如果线程超过设置个,其他线程会阻塞到这来,知道线程执行结束释放许可
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"进来了");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"走了");
        //释放一个请求
        semaphore.release();
    }


}
结果

Thread-0进来了
Thread-1进来了
Thread-2进来了

Thread-0走了
Thread-3进来了
Thread-2走了
Thread-4进来了
Thread-1走了
Thread-5进来了
Thread-3走了
Thread-6进来了
Thread-4走了
Thread-7进来了
Thread-5走了
Thread-8进来了
Thread-6走了
Thread-7走了
Thread-8走了
Thread-9进来了
Thread-9走了

解释:最大并发3个线程 只有线程进行 release() 方法后才会有别的线程执行 acquire()

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值