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. iTextSharp生成pdf含模板(二)---C#代码部分

    参考地址:https://www.cnblogs.com/ibeisha/p/itextsharp-pdf.html 一.先在程序中使用Nuget安装iTextSharp(我是创建的控制台程序) 二. ...

  2. Natasha V1.3.6.0 的升级日志

    开源库满足于个人,而完善于大众. Natasha 自稳定版发布之后,众多老铁参与增强改进,感谢如下老铁的反馈: 1. 异常搜集 在 wenjq0911 建议下,添加了异常捕获,现 Natasha 的编 ...

  3. Redis缓存数据库基础

    思维导图xmind文件:https://files-cdn.cnblogs.com/files/benjieming/Redis.zip

  4. Android开发之EditText多行文本输入

    <EditText android:id="@+id/add_content" android:layout_width="fill_parent" an ...

  5. django framework插件类视图方法

    1.使用类视图APIView重写API 类视图APIView,取代@api_view装饰器,代码如下: from rest_framework import status from rest_fram ...

  6. Eclipse properties配置文件中文乱码设置

    1. eclipse中properties的默认编码为  ISO-8859-1, 输入汉字会被转换为unicode 2. 点击  Windows-->preferences  按下图找到更改编码 ...

  7. jquery实现一些小动画一

    jquery实现小动画 <!DOCTYPE html> <html lang="en"> <head> <meta charset=&qu ...

  8. NBU恢复数据库数据文件报错RMAN-06091

    RMAN-06091: no channel allocated for maintenance (of an appropriate type) 一.错误信息 报错信息如下 Starting res ...

  9. 为什么说JAVA程序员必须掌握SpringBoot?

    原文链接:https://w.url.cn/s/AuDahfb SpringBoot 2.0 的推出又激起了一阵学习 SpringBoot 热,那么, SpringBoot 诞生的背景是什么?Spri ...

  10. Super Fish

        Super fish is a common fun and leisure game. It's a game that tests your intelligence and memory ...