从Semaphore的功能来看,我们基本能猜测到它的底层实现一定是基于AQS的共享所,因为需要实现多个线程共享一个领排池

创建 Semaphore 实例的时候,需要一个参数 permits,这个基本上可以确定是设置给 AQS 的 state 的,然后每个线程调用 acquire 的时候,执行 state = state - 1,release 的时候执行 state = state + 1,当然,acquire 的时候,如果 state = 0,说明没有资源了,需要等待其他线程
release。

Semaphore分公平策略和非公平策略

FairSync

static final class FairSync extends Sync { private static final long serialVersionUID = 2014338818796000944L; FairSync(int permits) { super(permits); } protected int tryAcquireShared(int acquires) { for (;;) { // 区别就在于是不是会先判断是否有线程在排队,然后才进行 CAS 减操作 if (hasQueuedPredecessors()) return -1; int available = getState(); int remaining = available - acquires; if (remaining < 0 || compareAndSetState(available, remaining)) return remaining; } }
} 

NofairSync

通过对比发现公平和非公平的区别就在于是否多了一个hasQueuedPredecessors的判断

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); }
}
final int nonfairTryAcquireShared(int acquires) { for (;;) { int available = getState(); int remaining = available - acquires; if (remaining < 0 || compareAndSetState(available, remaining)) return remaining; }
} 

由于后面的代码和CountDownLatch的是完全一样,都是基于共享锁的实现,所以也就没必要再花时间来分析了。

Semaphore源码分析相关推荐

  1. Semaphore 源码分析

    需要提前了解的知识点: AbstractQueuedSynchronizer 实现原理 类介绍 Semaphore(信号量)是用来控制同时访问特定资源的线程数量,它通过协调各个线程,以保证合理的使用公 ...

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

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

  3. Java并发编程(十六):CyclicBarrier源码分析

    前言   CyclicBarrier可以建立一个屏障,这个屏障可以阻塞一个线程直到指定的所有线程都达到屏障.就像团队聚餐,等所有人都到齐了再一起动筷子.根据Cyclic就可以发现CyclicBarri ...

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

    简介: 在多线程程序设计中有三个同步工具需要我们掌握,分别是Semaphore(信号量),countDownLatch(倒计数门闸锁),CyclicBarrier(可重用栅栏) 欢迎探讨,如有错误敬请 ...

  5. JAVA并发:并发工具类CountDownLatch、CyclicBarrier、Semaphore使用及源码分析

    在 JUC 下包含了一些常用的同步工具类,今天就来详细介绍一下,CountDownLatch,CyclicBarrier,Semaphore 的使用方法以及它们之间的区别. 1 CountDownLa ...

  6. kazoo源码分析:Zookeeper客户端start概述

    kazoo源码分析 kazoo-2.6.1 kazoo客户端 kazoo是一个由Python编写的zookeeper客户端,实现了zookeeper协议,从而提供了Python与zookeeper服务 ...

  7. celery源码分析-worker初始化分析(下)

    celery源码分析 本文环境python3.5.2,celery4.0.2,django1.10.x系列 celery的worker启动 在上文中分析到了Hub类的初始化,接下来继续分析Pool类的 ...

  8. 14.QueuedConnection和BlockingQueuedConnection连接方式源码分析

    QT信号槽直连时的时序和信号槽的连接方式已经在前面的文章中分析过了,见https://blog.csdn.net/Master_Cui/article/details/109011425和https: ...

  9. JStorm与Storm源码分析(八)--计时器工具-mk-timer

    Storm使用计时器线程来处理一些周期性调度事件. 与计时器相关的操作主要有:创建计时器线程.查看线程是否活跃.向线程中加入新的待调度事件.取消计时器线程 mk-timer方法用于创建一个计时器线程. ...

最新文章

  1. 2.微服务间调用ribbon
  2. 小记 cin/get/getline
  3. (转) mp4编码全介绍 (一)
  4. 强悍的vim —— 变量的访问
  5. Windows原版系统下载地址列表
  6. 阿里笔试--智能对话简化版之query指令槽位识别
  7. SpringCloud(13)之微服务的现状和未来
  8. 看《西游记》谈团队管理
  9. 曾经的大学德育论文,致敬天津理工大学
  10. 替代A4988的微型打印机驱动TMI8421国产电机驱动芯片
  11. Java开发-搭建基础开发环境(JDK、Maven、Tomcat、Git、Eclipse、IDEA)
  12. stata学习笔记|OLS回归
  13. 对 Viper RGB 驱动多个缓冲区溢出漏洞的分析
  14. Monkey测试手机BUG重现及解决方法
  15. 双面打印无效选择了文件服务器,使用高级选项打印(纸盘选择,双面打印,装订)...
  16. OTT TV系统你最关心的几个问题都在这
  17. 有梦想,生活就有方向
  18. asp.net Forms身份验证
  19. C语言实现随机抽奖程序
  20. php开启exec等函数

热门文章

  1. python 利用抛出异常并处理的优点
  2. POJ 1273 (基础最大流) Drainage Ditches
  3. fscanf和feof的组合使用
  4. Linux Kernel Makefile Test
  5. Google Map 自定义infowindow
  6. WCF 异常(原创:灰灰虫的家http://hi.baidu.com/grayworm)
  7. DataSet DataTable操作
  8. 笔试算法题(28):删除乱序链表中的重复项 找出已经排好序的两个数组中的相同项...
  9. Linux - 修改Cent OS系统的的hostname、配置DNS映射
  10. MFC 蜂鸣声或播放音频