JUC系列——Semaphore
简介
Semaphore是一种在多线程环境下负责协调各个线程,以保证它们能够正确、合理的使用公共资源。
Semaphore是一种计数信号量,用于管理一组资源,内部是基于AQS的共享模式。它相当于控制使用公共资源的活动线程的数量。
主要方法
主要方法:
Semaphore(int permits):构造方法,创建具有给定许可数的计数信号量并设置为非公平信号量。Semaphore(int permits,boolean fair):构造方法,当fair等于true时,创建具有给定许可数的计数信号量并设置为公平信号量。void acquire():从此信号量获取一个许可前线程将一直阻塞。相当于一辆车占了一个车位。void acquire(int n):从此信号量获取给定数目许可,在提供这些许可前一直将线程阻塞。比如n=2,就相当于一辆车占了两个车位。void release():释放一个许可,将其返回给信号量。就如同车开走返回一个车位。void release(int n):释放n个许可。int availablePermits():当前可用的许可数。
代码
- 示例
一个车位三辆车 模拟停车
public class SemaphoreDemo {private static final Semaphore SEMAPHORE = new Semaphore(1);private static final ThreadPoolExecutor THREAD_POOL = new ThreadPoolExecutor(5, 10, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<>());public static void main(String[] args) {for (int i = 1; i < 4; i++) {THREAD_POOL.execute(new Car(i));}}private static class Car extends Thread {private static final long START = System.currentTimeMillis();private final Integer number;public Car(Integer number) {this.number = number;}@Overridepublic void run() {try {PrintUtil.printNowObj(this + " waiting ...", START);SEMAPHORE.acquire();Thread.sleep(1000);PrintUtil.printNowObj(this + " In . Remaining parking spaces=" + SEMAPHORE.availablePermits(), START);SEMAPHORE.release();PrintUtil.printNowObj(this + " Out. Remaining parking spaces=" + SEMAPHORE.availablePermits(), START);} catch (InterruptedException e) {e.printStackTrace();}}@Overridepublic String toString() {return "Car{" +"number='" + number + '\'' +'}';}}
}
结果
curMills:1 Car{number=‘3’} waiting …
curMills:1 Car{number=‘1’} waiting …
curMills:1 Car{number=‘2’} waiting …
curMills:1003 Car{number=‘3’} In . Remaining parking spaces=0
curMills:1003 Car{number=‘3’} Out. Remaining parking spaces=1
curMills:2006 Car{number=‘1’} In . Remaining parking spaces=0
curMills:2006 Car{number=‘1’} Out. Remaining parking spaces=1
curMills:3011 Car{number=‘2’} In . Remaining parking spaces=0
curMills:3011 Car{number=‘2’} Out. Remaining parking spaces=1
Extend
- Semaphore的内部也是通过AQS的子类Sync实现,分为非公平和公平两种。
默认为非公平。 - acquire 之后抛异常 信号量不会自动归还。
所以 SEMAPHORE.release(); 尽量放到 finally 块中, 防止信号量流失。
JUC系列——Semaphore相关推荐
- AQS源码二探-JUC系列
Python微信订餐小程序课程视频 https://edu.csdn.net/course/detail/36074 Python实战量化交易理财系统 https://edu.csdn.net/cou ...
- 并发编程JUC系列及部分问题
什么是 CAS 吗? CAS(Compare And Swap)指比较并交换.CAS算法CAS(V, E, N)包含 3 个参数,V 表示要更新的变量,E 表示预期的值,N 表示新值.在且仅在 V 值 ...
- JUC系列(一)什么是JUC?
多线程一直Java开发中的难点,也是面试中的常客,趁着还有时间,打算巩固一下JUC方面知识,我想机会随处可见,但始终都是留给有准备的人的,希望我们都能加油!!! 沉下去,再浮上来,我想我们会变的不一样 ...
- JUC系列——基础知识 day1-1
JUC系列--基础知识 day1-1 JUC基础知识 进程 线程 进程和线程区别 并行与并发 同步 使用场景 异步 使用情景 QuickStart(new Thread方式创建新线程) 匿名内部类方式 ...
- JUC系列之线程池的使用
JUC系列文章目录 JUC系列往期文章 文章目录 JUC系列文章目录 前言 一.线程池 二.线程池构造函数的参数 三.线程池处理任务流程 四.如何自定义合适的线程池 五.如何正确关闭线程池 五.线程池 ...
- JUC系列1-基础知识
JUC系列-基础知识 线程启动 代码示例 继承Thread类 实现Runnable接口 利用FutureTask 线程常用方法 线程通知与等待 wait方法 notify方法 生产者与消费者代码示例 ...
- 突击并发编程JUC系列-ReentrantReadWriteLock
突击并发编程JUC系列演示代码地址: https://github.com/mtcarpenter/JavaTutorial 本章节将学习 ReentrantReadWriteLock(读写锁),Re ...
- JUC系列之并发队列
JUC系列文章目录 JUC系列往期文章 文章目录 JUC系列文章目录 前言 一.为什么要使用队列 二.ArrayBlockingQueue和LinkedBlockingQueue 1.LinkedBl ...
- JUC系列之ThreadLocal 的使用
JUC系列文章目录 JUC系列往期文章 文章目录 JUC系列文章目录 前言 一.ThreadLocal与Synchronized的区别 二.ThreadLocal的使用及原理 1.ThreadLoca ...
最新文章
- 下拉列表JComboBox,列表框JList
- 自己动手安装ARM交叉编译工具链
- Xamarin图表开发基础教程(12)OxyPlot框架支持的金融图表类型
- Spark is not running in local mode, therefore the checkpoint directory must not be on the local……
- 初探EntityFramework——来自数据库的Code First
- 信息学奥赛一本通(1208:2的幂次方表示)
- Asp.Net MVC 身份验证-Forms
- 头信息_如何在 Spring REST Controller 中获取 HTTP 头信息
- Java 已老,Kotlin 或将取而代之!
- java设置事务锁_事务与锁
- 凭证反过账 金蝶k3_金蝶软件k3凭证反过账
- 哆啦A梦的神奇口袋:帮你打破信息不对称,拒绝被割韭菜
- 牛客网-C语言编程入门训练
- Ubuntu18.04安装CAJ阅读器
- 红色警戒2修改器原理百科(五)
- kernel日志时间转换python脚本(MTK)
- Excel 如何制作时间轴
- 在拍拍二手爱回收出过一次手机后,我才体验到回收二手的快乐
- apple 兑换代码使用_什么是Apple True Tone,我该如何使用?
- 江苏移动CM101s-MV100-EMMC- M8233_强刷固件包