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源码分析的更多相关文章

  1. Semaphore 源码分析

    Semaphore 源码分析 1. 在阅读源码时做了大量的注释,并且做了一些测试分析源码内的执行流程,由于博客篇幅有限,并且代码阅读起来没有 IDE 方便,所以在 github 上提供JDK1.8 的 ...

  2. Java - "JUC" Semaphore源码分析

    Java多线程系列--“JUC锁”11之 Semaphore信号量的原理和示例 Semaphore简介 Semaphore是一个计数信号量,它的本质是一个"共享锁". 信号量维护了 ...

  3. 并发编程(七)——AbstractQueuedSynchronizer 之 CountDownLatch、CyclicBarrier、Semaphore 源码分析

    这篇,我们的关注点是 AQS 最后的部分,共享模式的使用.本文先用 CountDownLatch 将共享模式说清楚,然后顺着把其他 AQS 相关的类 CyclicBarrier.Semaphore 的 ...

  4. 并发编程之 Semaphore 源码分析

    前言 并发 JUC 包提供了很多工具类,比如之前说的 CountDownLatch,CyclicBarrier ,今天说说这个 Semaphore--信号量,关于他的使用请查看往期文章并发编程之 线程 ...

  5. Java并发系列[6]----Semaphore源码分析

    Semaphore(信号量)是JUC包中比较常用到的一个类,它是AQS共享模式的一个应用,可以允许多个线程同时对共享资源进行操作,并且可以有效的控制并发数,利用它可以很好的实现流量控制.Semapho ...

  6. java源码-Semaphore源码分析

    Semaphore内部Sync对象同样也是继承AQS,跟Reentrant一样有公平锁跟非公平锁区分,但是Semaphore是基于共享锁开发,Reentrant是基于独占锁开发.主要就是初始化Sema ...

  7. 【JUC】JDK1.8源码分析之Semaphore(六)

    一.前言 分析了CountDownLatch源码后,下面接着分析Semaphore的源码.Semaphore称为计数信号量,它允许n个任务同时访问某个资源,可以将信号量看做是在向外分发使用资源的许可证 ...

  8. Java并发包中Semaphore的工作原理、源码分析及使用示例

    1. 信号量Semaphore的介绍 我们以一个停车场运作为例来说明信号量的作用.假设停车场只有三个车位,一开始三个车位都是空的.这时如果同时来了三辆车,看门人允许其中它们进入进入,然后放下车拦.以后 ...

  9. 【JDK】JDK源码分析-Semaphore

    概述 Semaphore 是并发包中的一个工具类,可理解为信号量.通常可以作为限流器使用,即限制访问某个资源的线程个数,比如用于限制连接池的连接数. 打个通俗的比方,可以把 Semaphore 理解为 ...

随机推荐

  1. H5页面基础元素

    H5页面结构元素示例 <!DOCTYPE html> <html lang="zh"> <head> <meta charset=&quo ...

  2. 数据库系列(五)之 mysql的伸缩性

    这篇文章,主要讲述mysql的伸缩性.在国内mysql一直都是使用得最多的数据库,在国外也排名前三.mysql是一款开源的.性能较高的数据库. 伸缩性是指在软件设计中,软件(数据库.应用程序)通过特定 ...

  3. Gin-Go学习笔记六:Gin-Web框架 Api的编写

    Api编写 1>     Gin框架的Api返回的数据格式有json,xml,yaml这三种格式.其中yaml这种格式是一种特殊的数据格式.(本人暂时没有实现获取节点值得操作) 2>    ...

  4. nodeJs 报maximum call stack size exceeded js

    先看错误 查了下资料说是什么js堆栈异常,是递归造成的啥的,但我程序里没用到啥递归,整了老半天将collection-repeat换成ng-repeat然后就好啦,具体原因待探讨.

  5. CENTOS安装xwindow

    CentOS6安装图形界面 [root@centos6~]# yum -y install xorg* [root@centos6 ~]# yum -y groupinstall "X Wi ...

  6. 将积累多年的java学习资料,pdf文档给大家分享一下,比如《大话设计模式》《算法》《Linux私房菜》等等

    话不多说,资料目录如下,需要的拿走,下载的同时别忘了点下推荐. 需要的点下面链接,到小编网盘进行下载: 2-大话设计模式.pdf 链接:https://pan.baidu.com/s/1b05puNO ...

  7. windows,linux里的hosts文件

    在解析主机名的IP地址时,会先访问本机的上hosts文件,这样先配置好就可以不通过DNS服务器就获得IP地址. linux vi /etc/hosts IP 空格  主机名 windows C:\Wi ...

  8. TP5.0整合webuploader实现多图片上传功能

    在https://github.com/fex-team/webuploader 下载webuploader并解压,解压后放到public里面.其中我把解压缩后的文件夹改名为webuploader,放 ...

  9. Python:日常应用汇总

    判断路径中是否包含中文 import re def IsContainChinese(path:str) -> bool : cnPatter=re.compile(u'[\u4e00-\u9f ...

  10. Redis开启远程访问及密码

    一.开启远程访问 1.开放端口 firewall-cmd --zone=public --add-port=6379 firewall-cmd --zone=public --add-port=637 ...