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. 在IIS下发布.Net Core MVC项目

    1. 默认你已经安装了IIS,并且创建了一个.Net Core 项目 2. 发布.NET Core项目 在vs中右键点击MVC项目,点击"发布"按钮,选择"文件系统&qu ...

  2. 浅谈Spring中JDK动态代理与CGLIB动态代理

    前言Spring是Java程序员基本不可能绕开的一个框架,它的核心思想是IOC(控制反转)和AOP(面向切面编程).在Spring中这两个核心思想都是基于设计模式实现的,IOC思想的实现基于工厂模式, ...

  3. Android源码分析(十)-----关机菜单中如何添加飞行模式选项

    一:关机菜单添加飞行模式选项 源码路径:frameworks/base/core/res/res/values/config.xml 增加<item>airplane</item&g ...

  4. JavaWeb Listener之HttpSessionActivationListener ,session钝化、活化

    HttpSessionActivationListener    监听HttpSession对象的活化.钝化 钝化:将HttpSession对象从内存中转移至硬盘,存储为.session文件. 活化: ...

  5. 解决使用maven clean项目的时候报错,删除target文件夹失败

    背景:jdk1.8 + maven3.5.2 问题描述: 我在使用maven clean项目的时候,celan 失败,报错的原因是删除项目下的target文件夹下面的文件失败 解决方法: 打开任务管理 ...

  6. 字符串比较==和equals的区别

    <Stack Overflow 上 370万浏览量的一个问题:如何比较 Java 的字符串?> 比较详细的比较了==和equals方法的区别. 那借此机会,我就来梳理一下 Stack Ov ...

  7. python测试开发django-73.django视图 CBV 和 FBV

    前言 FBV(function base views) 就是在视图里使用函数处理请求,这一般是学django入门的时候开始使用的方式. CBV(class base views) 就是在视图里使用类处 ...

  8. MySQL 的各种 join

    table th:first-of-type { width: 200px; } join 类型 备注 left [outer] join right [outer] join union [all ...

  9. 海康SDK JAVA版本调用步骤及问题介绍

    一.前言 本文为海康SDK JAVA版本Demo的介绍,采用Eclipse运行,以及一些问题记录. 海康SDK版本:SDK_Win32 Eclipse版本:Mars2.0 JDK版本:1.8.0_15 ...

  10. JDBC连接池的九种查询

    package JDBC_Demo; import java.sql.SQLException; import java.util.List; import java.util.Map; import ...