Semaphore 基本原理

1. 概述

引入:
Semaphore 信号量是一个计数器,用来限制访问资源的线程的个数; 而不是限制的资源的个数;

Semaphore 和ReentrantLock的区别:
ReentrantLock只允许同一时刻线程的独占
而Semaphore用在共享资源有多个,也允许多个线程来访问这些资源;只是希望对访问的线程上限加以限制
两者底层都基于AQS;

使用场景:
1.使用 semaphore限流,访问高峰期时,让超出线程上限的请求线程阻塞,高峰期过去再释放许可;

2. 原理

2. 1 构造

semaphore构造函数和ReentrantLock一样,返回FairSnyc或NonfairSync; 这俩同步器继承自Sync,最终继承自AQS !

使用state来表示资源数量,也就是信号量,semaphore的构造函数需要指定state数量;
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在Sync类中,用setState()将信号量数量permits会传给state
在这里插入图片描述

在这里插入图片描述

2. 2 acquire() 获取资源

  1. 先获取State,然后使用CAS机制将state值改为减1,并返回剩余资源数; 如果剩余资源数大于0则获取成功
  2. 如果state减1之后小于0 ,线程进入阻塞队列等待:
    ①addWaiter() 先创建节点关联当前线程,
    ②加入阻塞队列的末尾,并将前驱节点的waitStatues设为-1 ,
    ③找到头节点,再尝试获取一次,失败则将当前线程park阻塞;
    在这里插入图片描述
    tryAcquireShared() 返回的是剩余的资源的数量,如果为负则表示失败,正数则成功;
    在这里插入图片描述
    在这里插入图片描述
    尝试使用CAS修改state,默认参数acquires是1,如果state<0或者修改成功,则将结果返回;
    在这里插入图片描述
    如果结果返回是state<0,则要阻塞当前线程:
    在这里插入图片描述
    执行addWaiter() 先创建节点关联当前线程,加入阻塞队列,并将前驱节点设为-1;
    找到头节点,再尝试获取一次,失败则将当前线程阻塞park;

2. 3 release() 释放资源

  1. 先拿到state,使用CAS机制将staet加 1,
  2. state释放成功就获取head头节点,如果head不为null 且weaitStatus是-1,就用unParkSuccsor() 释放头节点的后继节点;

在这里插入图片描述
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值