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的更多相关文章

  1. Java并发(6)- CountDownLatch、Semaphore与AQS

    引言 上一篇文章中详细分析了基于AQS的ReentrantLock原理,ReentrantLock通过AQS中的state变量0和1之间的转换代表了独占锁.那么可以思考一下,当state变量大于1时代 ...

  2. Java多线程系列--“JUC锁”11之 Semaphore信号量的原理和示例

    概要 本章,我们对JUC包中的信号量Semaphore进行学习.内容包括:Semaphore简介Semaphore数据结构Semaphore源码分析(基于JDK1.7.0_40)Semaphore示例 ...

  3. Java并发编程Semaphore

    信号量 信号量类Semaphore,用来保护对唯一共享资源的访问.一个简单的打印队列,并发任务进行打印,加入信号量同时之能有一个线程进行打印任务 . import java.util.concurre ...

  4. Java并发编程-Semaphore

    基于AQS的前世今生,来学习并发工具类Semaphore.本文将从Semaphore的应用场景.源码原理解析来学习这个并发工具类. 1. 应用场景 Semaphore用来控制同时访问某个特定资源的操作 ...

  5. J.U.C并发框架源码阅读(五)Semaphore

    基于版本jdk1.7.0_80 java.util.concurrent.Semaphore 代码如下 /* * ORACLE PROPRIETARY/CONFIDENTIAL. Use is sub ...

  6. 透过ReentrantLock窥探AQS

    背景 JDK1.5引入的并发包提供了一系列支持中等并发的类,这些组件是一系列的同步器,几乎任一同步器都可以实现其他形式的同步器,例如,可以用可重入锁实现信号量或者用信号量实现可重入锁.但是,这样做带来 ...

  7. 透过CountDownLatch窥探AQS

    本文来自公众号“Kahuna”,可搜索Alitaba119,欢迎关注,转载请注明出处,非常感谢 “ A synchronization aid that allows one or more thre ...

  8. Java并发指南9:AQS共享模式与并发工具类的实现

    一行一行源码分析清楚 AbstractQueuedSynchronizer (三) 转自:https://javadoop.com/post/AbstractQueuedSynchronizer-3 ...

  9. 1.3.4 并发工具类CountDownLatch/Semaphore/CyclicBarrier/FutureTask

    CountDownLatch的2个用途: 1. 所有线程都到达相同的起跑线后,再一起开始跑(并非同时开始,而是队列中一个唤醒另一个)[此情况需到达起跑线后再调用await()等待其他线程] 2. 所有 ...

随机推荐

  1. synchronized 的实现原理

    加不加 synchronized 有什么区别? synchronized 作为悲观锁,锁住了什么? synchronized 代码块怎么用 前面 3 篇文章讲了 synchronized 的同步方法和 ...

  2. DEDE中自定义表单HTML 怎么写

    用DEDE嵌套网站时,有时我们需要添加自定义字段,而自定义字段的HTML样式如何设置呢? 功能地图(核心/频道模型/内容模型管理/)——普通文章的修改——字段管理——你的自定义字段的修改——最下面自定 ...

  3. python学习03字符串基本操作

    '''字符串可以用单引号,双引号,三引号表示 '''#1.读取str1='I am a student!'#每一个字符对应一个下标,可以利用下标的方式来读取字符串对应的值——索引print(str1[ ...

  4. ansible的清单管理与模块应用(三)

  5. 啃算法:归并排序及JavaScript实现

    在学习归并排序之前,有必要了解分治法,因为归并排序正是应用了分治模式.(基本定义摘自<算法导论>) 一.分治法 1.思想: 将原问题分解为几个规模较小但类似于原问题的子问题,递归地求解这些 ...

  6. apache调优技巧之一隐藏apahce版本信息

    如果你的服务器版本信息是这样的,是很 危险的. [root@xinsz63 httpd-2.2.27]# curl -I 192.168.1.38 HTTP/1.1 403 Forbidden Dat ...

  7. php安装igbinary扩展(windows)

    pecl.php.net 是php的扩展仓库,访问此网站后,搜索需要安装的扩展,截图如下: igbinary: http://pecl.php.net/package/redis github的网址: ...

  8. document.documentElement.scrollTop指定位置失效解决办法

    近期在vue的H5项目中,做指定位置定位的时候发现使用document.documentElement.scrollTop一直不生效. 解决办法是document.documentElement.sc ...

  9. 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,- ...

  10. badboy 录制脚本

    第一步:介绍badboy工具 1.1: 页面功能分析: 1. 界面视图,模拟浏览器,能够进行操作 2. 需要录制脚本的URL 3. 点击运行URL 4. Summary:运行的各指标,响应时间,成功事 ...