九、并发工具类之Semaphore

流量控制 Semaphore

Semaphore是一个计数的信号量。初始化时分配一个配额permits。在访问前需要用acquire()方法申请一个配额,访问结束后调用release()释放配置。申请配额时如果配额不足将会阻塞。

例子:有2个足球,4个人射门练习。每个人射门后都要把球拿回来,后面的人才能射球。

public class Player implements  Runnable {

    private final Semaphore semaphore;

    public Player(Semaphore semaphore){
        this.semaphore=semaphore;
    }
    public void run() {
        try {
            semaphore.acquire();
            //踢完还剩余的球
            System.out.println("踢球。。。。"+semaphore.availablePermits());
            int millis = new Random().nextInt(4)+1;
            Thread.sleep(millis*1000);
            System.out.println(String.format("捡球花时间%d秒",millis));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            semaphore.release();
        }
    }
}


  public  static  void main(String[] args){

        Semaphore semaphore = new Semaphore(2);

        for(int i=0;i<4;i++){
            new Thread(new Player(semaphore)).start();
        }

        try {
            Thread.sleep(1000000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

结果

踢球。。。。1
踢球。。。。0
捡球花时间4秒
捡球花时间4秒
踢球。。。。0
踢球。。。。0
捡球花时间1秒
捡球花时间2秒

 

  1. Semaphore内部是由共享锁实现的。
  2. Semaphore支持公平锁和非公平锁。默认是非公平锁。可以通过构造函数设置。

常用API

void acquire() 
从该信号量获取许可证,阻止直到可用,或线程为 interrupted 。  
void acquire(int permits) 
从该信号量获取给定数量的许可证,阻止直到所有可用,否则线程为 interrupted 。  
void acquireUninterruptibly() 
从这个信号灯获取许可证,阻止一个可用的。  
void acquireUninterruptibly(int permits) 
从该信号量获取给定数量的许可证,阻止直到所有可用。  
int availablePermits() 
返回此信号量中当前可用的许可数。  
int drainPermits() 
获取并返回所有可立即获得的许可证。  
protected Collection<Thread> getQueuedThreads() 
返回一个包含可能正在等待获取的线程的集合。  
int getQueueLength() 
返回等待获取的线程数的估计。  
boolean hasQueuedThreads() 
查询任何线程是否等待获取。  
boolean isFair() 
如果此信号量的公平设置为真,则返回 true 。  
protected void reducePermits(int reduction) 
缩小可用许可证的数量。  
void release() 
释放许可证,将其返回到信号量。  
void release(int permits) 
释放给定数量的许可证,将其返回到信号量。  
String toString() 
返回一个标识此信号量的字符串及其状态。  
boolean tryAcquire() 
从这个信号量获得许可证,只有在调用时可以使用该许可证。  
boolean tryAcquire(int permits) 
从这个信号量获取给定数量的许可证,只有在调用时全部可用。  
boolean tryAcquire(int permits, long timeout, TimeUnit unit) 
从该信号量获取给定数量的许可证,如果在给定的等待时间内全部可用,并且当前线程尚未 interrupted 。  
boolean tryAcquire(long timeout, TimeUnit unit) 
如果在给定的等待时间内可用,并且当前线程尚未 到达 interrupted,则从该信号量获取许可。  

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值