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. 所有 ...
随机推荐
- Jwt认识与攻击
今天看到2018强网杯的题目,因此总结一下. Json Web Token Json Web Token简称jwt 那么怎么样可以让HTTP记住曾经发生的事情呢? 这里的选择可以很多:cookie,s ...
- Laravel - 上手实现 - 文件上传、保存到 public 目录下
1.为了访问方便,将上传的文件保存在 public 目录下,需要进行修改配置. 找到 config/filesystems.php 文件然后修改 root.具体如下: 'local' => [ ...
- redis: 主从复制和哨兵模式(十三)
redis 主从复制 最低要求是一主二从(一个主机和两个从机) 主机才能写 从机只能读 只要从机连接到主机 数据就会全量复制到从机 环境配置(同一台机器) 1:配置文件 redis.conf配置如下: ...
- Des对称可逆加密
/// <summary> /// DES AES Blowfish /// 对称加密算法的优点是速度快, /// 缺点是密钥管理不方便,要求共享密钥. /// 可逆对称加密 密钥长 ...
- 大数据hbase分布式安装及其部署。
大数据hbase分布式安装及其部署. 首先要启动Hadoop以及zookeeper,可以参考前面发布的文章. 将hbase的包上传至master节点 这里我使用的是1.3.6的版本,具体的根据自己的版 ...
- libcurl vs HTTP 1.1, 返回值100.
easy_perform 会处理返回值100的情况,即先发送头文件再发送data. 但是如果timeout (CURLOPT_TIMEOUT)时间到了,这个100返回值是会被easy_perform返 ...
- 一千行mysql笔记
原文地址:https://shockerli.net/post/1000-line-mysql-note/ /* Windows服务 */ -- 启动MySQL net start mysql -- ...
- HTML中使用CSS样式(下)
上节内容回顾加补充: 补充:默认img标签,有一个1px的边框 如果点击图片跳转到连接,a标签下套img标签,在IE有的版本中,会有蓝色边框. <a href="http://blog ...
- 详解Linux 安装 JDK、Tomcat 和 MySQL(图文并茂)
https://www.jb51.net/article/120984.htm
- CentOS+Subversion 配置Linux 下 SVN服务器
1.安装#yum install subversion测试安装是否成功:#svnserve –version 回车显示版本说明安装成功 2.配置 ·建立版本库 #mkdir /opt/svnd ...