java.util.concurrent并发包之Semaphore

一、Semaphore类

Semaphore是一个线程同步辅助类;
可以维护当前访问自身线程的线程个数,提供线程同步机制;
Semaphore可以控制同时访问资源的线程数;
Semaphore是一个计数器的信号量;
Semaphore常用于限制可以访问某些资源的线程数量;

二、Semaphore类的使用

初始化;
增加;
减少;

ExecutorService executorService  = Executors.newCachedThreadPool();
//初始化信号量,只允许3个线程同事访问
Semaphore semaphore = new Semaphore(3);
for (int i = 0; i < 10; i++) {
    final long num = i;
    executorService.submit(() -> {
        try {
            //允许访问许可
            semaphore.acquire();
            //执行
            System.out.println("Accessing..."+num);
            //模拟随机时长
            Thread.sleep(new Random().nextInt(5000));
            //释放
            semaphore.release();
            System.out.println("release..." + num);
        } catch (InterruptedException e) {

        }
    });
}
executorService.shutdown();

三、Semaphore 类中的方法

acquire()  
获取一个令牌,在获取到令牌、或者被其他线程调用中断之前线程一直处于阻塞状态。
​
acquire(int permits)  
获取一个令牌,在获取到令牌、或者被其他线程调用中断、或超时之前线程一直处于阻塞状态。
    
acquireUninterruptibly() 
获取一个令牌,在获取到令牌之前线程一直处于阻塞状态(忽略中断)。
    
tryAcquire()
尝试获得令牌,返回获取令牌成功或失败,不阻塞线程。
​
tryAcquire(long timeout, TimeUnit unit)
尝试获得令牌,在超时时间内循环尝试获取,直到尝试获取成功或超时返回,不阻塞线程。
​
release()
释放一个令牌,唤醒一个获取令牌不成功的阻塞线程。
​
hasQueuedThreads()
等待队列里是否还存在等待线程。
​
getQueueLength()
获取等待队列里阻塞的线程数。
​
drainPermits()
清空令牌把可用令牌数置为0,返回清空令牌的数量。
​
availablePermits()
返回可用的令牌数量。

四、例子:用Semaphore实现排队买票

class SemaphoreRunable implements Runnable{
    private Semaphore semaphore;//信号量
    private int user;//记录第几个用户

    public SemaphoreRunable(Semaphore semaphore,int user){
        this.semaphore=semaphore;
        this.user=user;
    }
    public void run() {
        try {
            //获取型号量许可
            semaphore.acquire();
            System.out.println("用户【"+user+"】进入窗口,准备买票");
            Thread.sleep((long)(Math.random()*10000));
            System.out.println("用户【"+user+"】买票完成,即将离开...");
            Thread.sleep((long)(Math.random()*10000));
            System.out.println("用户【"+user+"】离开售票窗口...");
            //释放
            semaphore.release();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
}

private void execute(){
    //定义窗口个数
    final Semaphore semaphore=new Semaphore(10);   //信号量 控制并发线程数
    //线程池
    ExecutorService threadPool= Executors.newCachedThreadPool();
    //模拟20个用户
    for (int i=0;i<20;i++){
        //执行买票
        threadPool.execute(new SemaphoreRunable(semaphore,(i+1)));
    }
}

public static void main(String[] args) {
    SemaphoreDemo sd=new SemaphoreDemo();
    sd.execute();
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值