这期内容当中小编将会给大家带来有关并发编程之Semaphore的使用方法,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。
线程去获取锁首先查看线程是否有中断标志,有就抛异常,没有就尝试去获取锁,代码如下:
如果队列是空的,获取当前抽象队列的state,当前的state-资源数的差值大于0(说明尝试获取锁成功),cas将当前state改成差值,并返回(整个过程自旋+cas保证了尝试获取锁成功并修改state的原子性。);如果队列有排队的节点(尝试获取锁失败返回-1)或者队列没有排队节点但是差值小于0(尝试获取锁失败,资源数太多)就要入队,代码如下:
这里和排他锁的区别是参数为共享模式,同样队列为空就初始化队列(自旋+cas保证了初始化队列的原子性),不为空就入队。判断当前节点的前节点是否是head节点,如果是,再次尝试获取锁,如果失败,或者当前节点的前节点不是head就将前节点的ws改为-1,阻塞当前线程park。
如果有线程释放锁,代码如下:
尝试释放共享锁,代码如下:
获取抽象队列的state,将state+1(不一定为+1)的和,cas将state修改成和,尝试释放锁成功。唤醒后续节点,代码如下:
唤醒头节点把头节点的ws=-1,将其修改为0,然后唤醒,代码如下:
如果头节点的ws=-1<0将其cas为0,下一个节点不为空,unpark(下一节点的线程),线程在阻塞的位置被唤醒,尝试获取锁,代码如下:
在循环中被唤醒,继续尝试获取锁,如果和上一次一样失败,则继续park阻塞。尝试获取锁成功int r = tryAcquireShared(arg)>=0,代码如下:
将当前节点设置为head(head=当前节点,当前节点的pre=null,thread=null)意味着前节点要被踢出队列(差一步修改前节点的next=null),当前节点下一节点为空,将前节点的next=null,前节点出队完成,获取锁成功;
反之下一节点不为空(下一节点会在阻塞park前将前节点的ws=-1)并且为共享模式释放锁,代码如下:
这里会将新的头节点的ws=-1改为0,唤醒下一节点,代码如下:
唤醒下一线程,下一线程在阻塞的循环中被唤醒,尝试获取锁,失败再次阻塞park,成功就继续这一步骤,一直传播下去,也就是唤醒多个节点
上述就是小编为大家分享的并发编程之Semaphore的使用方法了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注亿速云行业资讯频道。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。