多线程基础(九)信号量Semaphore——[ˈseməfɔːr]

1. Semaphore----[ˈseməfɔːr]
信号量可以理解为限流算法令牌算法里的令牌池,他是对锁的扩展,无论synchronized还是Lock一次只允许一个线程访问资源,而Semaphore内部维护了一个信号量计数器,当线程访问资源时将计数器减一,访问完毕后计数器加一,当计数器减到0时再有线程来获取锁将会等待,当有一个线程执行完毕释放锁后计数器加一不为0,此时等待的线程可以获取锁并把计数器减一。
其构造函数:
public Semaphore(int permits)
public Semaphore(int permits, boolean fair)
permits:信号计数器初始值
fair:是否公平锁
其常用方法:
acquire()
tryAcquire()
tryAcquire(long timeout, TimeUnit unit)
acquireUninterruptibly():不响应中断
release()
用法与Lock的相关用法是一样的,这里不细述了,可以看多线程基础(四)Lock

2. 示例
控制最多同时只能有两个线程拿到锁

public class Test05 {
    // [ˈseməfɔːr] 信号量
    private static Semaphore semaphore = new Semaphore(2);
    private static int coreSize = 10;
    private static long timeOut = 10;
    private static LinkedBlockingQueue queue = new LinkedBlockingQueue<>();
    private static TimeUnit timeUnit = TimeUnit.SECONDS;
    private static AtomicInteger index = new AtomicInteger(0);

    public static void main(String[] args) {
        ThreadPoolExecutor executor = new ThreadPoolExecutor(coreSize, coreSize, timeOut, timeUnit, queue);
        long start = System.currentTimeMillis();
        for (int i = 0; i < 8; i++) {
            executor.submit(() -> {
                try {
                    semaphore.acquire();
                    TimeUnit.SECONDS.sleep(1);
                    int name = index.incrementAndGet();
                    System.out.println("第" + name + "个线程执行完毕:" + (System.currentTimeMillis() - start) / 1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    semaphore.release();
                }
            });
        }
        executor.shutdown();
    }
}

执行结果:

第1个线程执行完毕:1
第2个线程执行完毕:1
第3个线程执行完毕:2
第4个线程执行完毕:2
第5个线程执行完毕:3
第6个线程执行完毕:3
第7个线程执行完毕:4
第8个线程执行完毕:4
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值