Semaphore源码分析

public class SemaphoreExample1 {
private final static int threadCount = ;
public static void main(String[] args) throws Exception {
ExecutorService exec = Executors1.newCachedThreadPool();
final Semaphore1 semaphore = new Semaphore1(); //并发数是3,每3个3个打印
for (int i = ; i < ; i++) {
exec.execute(() -> {
try {
semaphore.acquire(); // 获取一个许可,多线程访问
System.out.println("咔咔咔咔咔咔扩扩扩扩扩扩扩");
semaphore.release(); // 释放一个许可,多线程访问
} catch (Exception e) {
}
});
}
exec.shutdown();
}
}
//共享锁,跟读写锁的读锁是一样的逻辑。
public class Semaphore1 implements java.io.Serializable {
private static final long serialVersionUID = -3222578661600680210L;
private final Sync sync; abstract static class Sync extends AbstractQueuedSynchronizer1 {
private static final long serialVersionUID = 1192457210091910933L; Sync(int permits) {
setState(permits);//state
} final int getPermits() {
return getState();
} final int nonfairTryAcquireShared(int acquires) {//获取许可,多线程
for (;;) {//死循环,直到获取一个许可。只有在许可没了才去排队
int available = getState();
int remaining = available - acquires;//state减1
if (remaining < || compareAndSetState(available, remaining))//,多线程
return remaining;
}
} protected final boolean tryReleaseShared(int releases) {//释放许可,多线程访问
for (;;) {
int current = getState();
int next = current + releases;
if (next < current) // overflow
throw new Error("Maximum permit count exceeded");
if (compareAndSetState(current, next))//减一成功,别的线程就可以获取了。
return true;
}
} final void reducePermits(int reductions) {
for (;;) {
int current = getState();
int next = current - reductions;
if (next > current) // underflow
throw new Error("Permit count underflow");
if (compareAndSetState(current, next))
return;
}
} final int drainPermits() {
for (;;) {
int current = getState();
if (current == || compareAndSetState(current, ))
return current;
}
}
} static final class NonfairSync extends Sync {
private static final long serialVersionUID = -2694183684443567898L; NonfairSync(int permits) {
super(permits);
} protected int tryAcquireShared(int acquires) {//获取许可,多线程
return nonfairTryAcquireShared(acquires);
}
} static final class FairSync extends Sync {
private static final long serialVersionUID = 2014338818796000944L; FairSync(int permits) {
super(permits);
} protected int tryAcquireShared(int acquires) {//获取许可
for (;;) {//死循环,直到获取一个许可。只有在许可没了才去排队
if (hasQueuedPredecessors())//要不要去排队
return -;
int available = getState();
int remaining = available - acquires;
if (remaining < || compareAndSetState(available, remaining))
return remaining;
}
}
} public Semaphore1(int permits) {
sync = new NonfairSync(permits);
} public Semaphore1(int permits, boolean fair) {
sync = fair ? new FairSync(permits) : new NonfairSync(permits);
} public void acquire() throws InterruptedException {//多线程访问
sync.acquireSharedInterruptibly();//获取共享锁
} public void acquireUninterruptibly() throws InterruptedException {
sync.acquireShared();
} public boolean tryAcquire() {//没有获取许可的,就丢弃,不排队
return sync.nonfairTryAcquireShared() >= ;
} public boolean tryAcquire(long timeout, TimeUnit unit) throws InterruptedException {
return sync.tryAcquireSharedNanos(, unit.toNanos(timeout));
} public void release() {//多线程访问
sync.releaseShared();
} public void acquire(int permits) throws InterruptedException {
if (permits < ) throw new IllegalArgumentException();
sync.acquireSharedInterruptibly(permits);
} public void acquireUninterruptibly(int permits) throws InterruptedException {
if (permits < ) throw new IllegalArgumentException();
sync.acquireShared(permits);
} public boolean tryAcquire(int permits) {
if (permits < ) throw new IllegalArgumentException();
return sync.nonfairTryAcquireShared(permits) >= ;
} public boolean tryAcquire(int permits, long timeout, TimeUnit unit)
throws InterruptedException {
if (permits < ) throw new IllegalArgumentException();
return sync.tryAcquireSharedNanos(permits, unit.toNanos(timeout));
} public void release(int permits) {
if (permits < ) throw new IllegalArgumentException();
sync.releaseShared(permits);
} public int availablePermits() {
return sync.getPermits();
} public int drainPermits() {
return sync.drainPermits();
} protected void reducePermits(int reduction) {
if (reduction < ) throw new IllegalArgumentException();
sync.reducePermits(reduction);
} public boolean isFair() {
return sync instanceof FairSync;
} public final boolean hasQueuedThreads() {
return sync.hasQueuedThreads();
} public final int getQueueLength() {
return sync.getQueueLength();
} protected Collection<Thread> getQueuedThreads() {
return sync.getQueuedThreads();
} public String toString() {
return super.toString() + "[Permits = " + sync.getPermits() + "]";
}
}
Semaphore源码分析的更多相关文章
- Semaphore 源码分析
Semaphore 源码分析 1. 在阅读源码时做了大量的注释,并且做了一些测试分析源码内的执行流程,由于博客篇幅有限,并且代码阅读起来没有 IDE 方便,所以在 github 上提供JDK1.8 的 ...
- Java - "JUC" Semaphore源码分析
Java多线程系列--“JUC锁”11之 Semaphore信号量的原理和示例 Semaphore简介 Semaphore是一个计数信号量,它的本质是一个"共享锁". 信号量维护了 ...
- 并发编程(七)——AbstractQueuedSynchronizer 之 CountDownLatch、CyclicBarrier、Semaphore 源码分析
这篇,我们的关注点是 AQS 最后的部分,共享模式的使用.本文先用 CountDownLatch 将共享模式说清楚,然后顺着把其他 AQS 相关的类 CyclicBarrier.Semaphore 的 ...
- 并发编程之 Semaphore 源码分析
前言 并发 JUC 包提供了很多工具类,比如之前说的 CountDownLatch,CyclicBarrier ,今天说说这个 Semaphore--信号量,关于他的使用请查看往期文章并发编程之 线程 ...
- Java并发系列[6]----Semaphore源码分析
Semaphore(信号量)是JUC包中比较常用到的一个类,它是AQS共享模式的一个应用,可以允许多个线程同时对共享资源进行操作,并且可以有效的控制并发数,利用它可以很好的实现流量控制.Semapho ...
- java源码-Semaphore源码分析
Semaphore内部Sync对象同样也是继承AQS,跟Reentrant一样有公平锁跟非公平锁区分,但是Semaphore是基于共享锁开发,Reentrant是基于独占锁开发.主要就是初始化Sema ...
- 【JUC】JDK1.8源码分析之Semaphore(六)
一.前言 分析了CountDownLatch源码后,下面接着分析Semaphore的源码.Semaphore称为计数信号量,它允许n个任务同时访问某个资源,可以将信号量看做是在向外分发使用资源的许可证 ...
- Java并发包中Semaphore的工作原理、源码分析及使用示例
1. 信号量Semaphore的介绍 我们以一个停车场运作为例来说明信号量的作用.假设停车场只有三个车位,一开始三个车位都是空的.这时如果同时来了三辆车,看门人允许其中它们进入进入,然后放下车拦.以后 ...
- 【JDK】JDK源码分析-Semaphore
概述 Semaphore 是并发包中的一个工具类,可理解为信号量.通常可以作为限流器使用,即限制访问某个资源的线程个数,比如用于限制连接池的连接数. 打个通俗的比方,可以把 Semaphore 理解为 ...
随机推荐
- 阿里云Centos7用putty ssh链接掉线
解决方法:修改云服务器 ssh 配置文件(修改前一定要先备份) (1)打开配置文件: vim /etc/ssh/sshd_config 1 (2)找到下面两行: ClientAliveInterval ...
- tempermonkey文档及为google翻译添加清除输入框脚本
想通过tempermonkey为google增加一个清除输入框的快捷键,这本来是很好做的事情,后来也证明确实是那么简单,不过中间遇到了几个奇怪的问题,有必要记录一下 tempermonkey 文档:h ...
- python 排序 桶排序
算法思想: 桶排序将数组分到有限数量的桶里.然后每个桶里再分别排序(使用任何算法) 当要倍排序的数组内的数值时均匀分配的时候,桶排序使用线性时间O(n) 步骤: 根据最大值.最小值.桶内数据范围设定一 ...
- SQL报错注入
0x00:前言 sqli-libs第11关的报错注入,之前没有具体学习了解过,所以单独学习一下. 0x01:例子 uname=1&passwd=1' union select count(*) ...
- SPL06-001 气压计
歌尔是全球领先的MEMS厂家,最新推出新款气压传感器SPL06-001,定位精度可达5cm 手册地址 https://download.csdn.net/download/zhangxuechao_/ ...
- OEL7.6设置光盘YUM源
先把原来的yum源改名让他失效 mv public-yum-ol7.repo public-yum-ol7.repo.bak 然后新建个yum源 [root@localhost yum.repos.d ...
- Vue axios异步获取后台数据alert提示undefined
记录一个小问题,关于分页查询套餐 前台通过axios异步请求获取后台数据alert弹出数据提示undefined 下面有三个bean PageResult /** * 分页结果封装对象 */ publ ...
- c# MVC5(二) MVC与IOC结合
今天主要来讲解使用Unity来自动注入.Unity前面我们已经详细的介绍过了,如有需要请自行前往去看,今天我们的重点是说MVC与IOC的结合. IOC:控制反转,控制反转的工具是DI(依赖注入:构造函 ...
- 基于开源博客系统(mblog)搭建网站
基于开源博客系统(mblog)搭建网站 上一章讲了基于jpress部署的博客系统,这一章了解一下 mblog这个开源的基于springboot的博客系统,相比与jpress 的热度fork数量要少一些 ...
- Java使用枚举来消除if else(转载)
Java代码里经常出现多个if else会大大降低效率,我们可以使用枚举的方式来代替if else,示例代码如下: public enum Grade { A_10_90(90, 100, " ...