Semaphore和AQS
Semaphore意思的信号量,它的作用是控制访问特定资源的线程数量
构造方法:
public Semaphore(int permits)
public Semaphore(int permits, boolean fair)
permits:允许同时访问的线程数量
fair:是否公平,若true的话,下次执行的会是先进去等待的线程(先入先出)
使用:
acquire():获取许可执行
release():释放许可,让其他线程获取许可执行。
显然这个功能可以用于资源访问控制或者是限流的操作。
如下代码每次只会有两个线程执行。
package com.nijunyang.concurrent; import java.util.concurrent.Semaphore; /**
* Description:
* Created by nijunyang on 2020/5/13 23:31
*/
public class SemaphoreTest {
Semaphore semaphore; public SemaphoreTest(Semaphore semaphore) {
this.semaphore = semaphore;
} public static void main(String[] args) {
SemaphoreTest semaphoreTest = new SemaphoreTest(new Semaphore(2, true));
for (int i = 0; i < 10; i++) {
Thread thread = new Thread(() -> {
try {
semaphoreTest.test();
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "线程" + i);
thread.start();
}
System.out.println("线程创建完毕.");
} public void test() throws InterruptedException {
semaphore.acquire();
System.out.println(Thread.currentThread().getName() + "执行.");
Thread.sleep(4000);
semaphore.release();
}
}
原理:
进入Semaphore的代码一看,又见到AQS,前面ReentrantLock中用到的是独占模式,Semaphore中就是共享模式了。和ReentrantLock如出一辙,内部类Sync继承了AbstractQueuedSynchronizer,同时有两个子类实现一个公平FairSync,另一个非公平NonfairSync。
构造方法传入的permits,最终会赋值到AbstractQueuedSynchronizer的state字段,这个字段的ReentrantLock中是用来计算锁重入的。但是在Semaphore里面字段是用来控制资源访问数量的。
1.acquire方法获取的许可的时候 先去扣减,将state的值-1,如果结果不小于0,就通过CAS操作修改state的值,最后返回当前剩余许可

2. 如果返回的许可剩余数量小于0 就执行doAcquireSharedInterruptibly方法,将当前线程以共享的模式加入到队列中去


3. 拿到前驱结点,根据结点的几个状态去判断前驱结点是否是取消或者其他状态,如果取消状态就剔除出去

4.release方法 释放许可 CAS操作将state的值+1

5.设置成功了执行doReleaseShared方法,去唤醒队列中等待的线程,获取到许可执行


Semaphore和AQS的更多相关文章
- Java并发(6)- CountDownLatch、Semaphore与AQS
引言 上一篇文章中详细分析了基于AQS的ReentrantLock原理,ReentrantLock通过AQS中的state变量0和1之间的转换代表了独占锁.那么可以思考一下,当state变量大于1时代 ...
- Java多线程系列--“JUC锁”11之 Semaphore信号量的原理和示例
概要 本章,我们对JUC包中的信号量Semaphore进行学习.内容包括:Semaphore简介Semaphore数据结构Semaphore源码分析(基于JDK1.7.0_40)Semaphore示例 ...
- Java并发编程Semaphore
信号量 信号量类Semaphore,用来保护对唯一共享资源的访问.一个简单的打印队列,并发任务进行打印,加入信号量同时之能有一个线程进行打印任务 . import java.util.concurre ...
- Java并发编程-Semaphore
基于AQS的前世今生,来学习并发工具类Semaphore.本文将从Semaphore的应用场景.源码原理解析来学习这个并发工具类. 1. 应用场景 Semaphore用来控制同时访问某个特定资源的操作 ...
- J.U.C并发框架源码阅读(五)Semaphore
基于版本jdk1.7.0_80 java.util.concurrent.Semaphore 代码如下 /* * ORACLE PROPRIETARY/CONFIDENTIAL. Use is sub ...
- 透过ReentrantLock窥探AQS
背景 JDK1.5引入的并发包提供了一系列支持中等并发的类,这些组件是一系列的同步器,几乎任一同步器都可以实现其他形式的同步器,例如,可以用可重入锁实现信号量或者用信号量实现可重入锁.但是,这样做带来 ...
- 透过CountDownLatch窥探AQS
本文来自公众号“Kahuna”,可搜索Alitaba119,欢迎关注,转载请注明出处,非常感谢 “ A synchronization aid that allows one or more thre ...
- Java并发指南9:AQS共享模式与并发工具类的实现
一行一行源码分析清楚 AbstractQueuedSynchronizer (三) 转自:https://javadoop.com/post/AbstractQueuedSynchronizer-3 ...
- 1.3.4 并发工具类CountDownLatch/Semaphore/CyclicBarrier/FutureTask
CountDownLatch的2个用途: 1. 所有线程都到达相同的起跑线后,再一起开始跑(并非同时开始,而是队列中一个唤醒另一个)[此情况需到达起跑线后再调用await()等待其他线程] 2. 所有 ...
随机推荐
- synchronized 的实现原理
加不加 synchronized 有什么区别? synchronized 作为悲观锁,锁住了什么? synchronized 代码块怎么用 前面 3 篇文章讲了 synchronized 的同步方法和 ...
- DEDE中自定义表单HTML 怎么写
用DEDE嵌套网站时,有时我们需要添加自定义字段,而自定义字段的HTML样式如何设置呢? 功能地图(核心/频道模型/内容模型管理/)——普通文章的修改——字段管理——你的自定义字段的修改——最下面自定 ...
- python学习03字符串基本操作
'''字符串可以用单引号,双引号,三引号表示 '''#1.读取str1='I am a student!'#每一个字符对应一个下标,可以利用下标的方式来读取字符串对应的值——索引print(str1[ ...
- ansible的清单管理与模块应用(三)
- 啃算法:归并排序及JavaScript实现
在学习归并排序之前,有必要了解分治法,因为归并排序正是应用了分治模式.(基本定义摘自<算法导论>) 一.分治法 1.思想: 将原问题分解为几个规模较小但类似于原问题的子问题,递归地求解这些 ...
- apache调优技巧之一隐藏apahce版本信息
如果你的服务器版本信息是这样的,是很 危险的. [root@xinsz63 httpd-2.2.27]# curl -I 192.168.1.38 HTTP/1.1 403 Forbidden Dat ...
- php安装igbinary扩展(windows)
pecl.php.net 是php的扩展仓库,访问此网站后,搜索需要安装的扩展,截图如下: igbinary: http://pecl.php.net/package/redis github的网址: ...
- document.documentElement.scrollTop指定位置失效解决办法
近期在vue的H5项目中,做指定位置定位的时候发现使用document.documentElement.scrollTop一直不生效. 解决办法是document.documentElement.sc ...
- 51 NOD 1049 最大子段和 动态规划 模板 板子 DP
N个整数组成的序列a[1],a[2],a[3],-,a[n],求该序列如a[i]+a[i+1]+-+a[j]的连续子段和的最大值.当所给的整数均为负数时和为0. 例如:-2,11,-4,13,-5,- ...
- badboy 录制脚本
第一步:介绍badboy工具 1.1: 页面功能分析: 1. 界面视图,模拟浏览器,能够进行操作 2. 需要录制脚本的URL 3. 点击运行URL 4. Summary:运行的各指标,响应时间,成功事 ...