首页 > 编程语言 >Semaphore源码阅读

Semaphore源码阅读

时间:2024-01-31 14:35:29浏览次数:27  
标签:令牌 int Sync final 源码 线程 阅读 Semaphore remaining

目录

本人的源码阅读主要聚焦于类的使用场景,一般只在java层面进行分析,没有深入到一些native方法的实现。并且由于知识储备不完整,很可能出现疏漏甚至是谬误,欢迎指出共同学习

本文基于corretto-17.0.9源码,参考本文时请打开相应的源码对照,否则你会不知道我在说什么

简介

semaphore翻译过来即信号量,对semaphore最直观的解释就是,信号量是一个令牌桶,如果桶里的令牌数>=线程想要获取的令牌数,那么线程就能获取到令牌,然后继续执行,否则就要阻塞等待其他线程将令牌放入桶里,直到桶里令牌数足够,非常简单。

不像JUC里的Lock,线程只能释放自己获得的锁,即Lock有owner的概念,不能随便释放其他人的锁。而semaphore中令牌没有owner的概念,任何线程都能随意往桶里放令牌。

代码分析

成员变量

public class Semaphore implements java.io.Serializable {
  private final Sync sync;
}

成员变量非常简单只有一个,看到Sync就该知道这个是AQS了。信号量还支持fairness,因此Sync作为抽象基类,实现了NonFairSync和FairSync。

方法

Sync

Sync继承自AQS,state定义为桶中令牌数量。由于可能同时有多个线程获得令牌,自然需要重写AQS的两个方法:

  • tryAcquireShared
  • tryReleaseShared

在tryAcquire这里需要区分公平与否,在之前的文章说过,公平的tryAcquire通过检查是否有前驱等待者,即下面两个条件满足一个都属于有前驱等待者,那么就直接tryAcquire失败:

  • 当前线程没进入阻塞队列,且队列不为空
  • 当前线程已经在阻塞队列中,但前面有更靠近队头(等待时间更长)的线程

否则如果是非公平的,就直接尝试更改state即可。

abstract static class Sync extends AbstractQueuedSynchronizer {
  // 初始化state为令牌数量
  Sync(int permits) {
    setState(permits);
  }

  final int getPermits() {
    return getState();
  }

  // nonfair版本的tryAcquireShared,如果目前令牌足够,直接更改令牌数(state)即可
  final int nonfairTryAcquireShared(int acquires) {
    for (;;) {
      int available = getState();
      int remaining = available - acquires;
      if (remaining < 0 ||
        compareAndSetState(available, remaining))
        return remaining;
    }
  }

  // 往桶里放令牌,直接更改state
  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;
    }
  }
  
  // 忽略其他非核心方法
}

NonFairSync

static final class NonfairSync extends Sync {
  NonfairSync(int permits) {
    super(permits);
  }

  // 非公平tryAcquire
  protected int tryAcquireShared(int acquires) {
    return nonfairTryAcquireShared(acquires);
  }
}

FairSync

static final class FairSync extends Sync {
  private static final long serialVersionUID = 2014338818796000944L;

  FairSync(int permits) {
    super(permits);
  }

  // 公平tryAcquire
  protected int tryAcquireShared(int acquires) {
    for (;;) {
      // 检查是否有阻塞更久的线程
      if (hasQueuedPredecessors())
        return -1;
      int available = getState();
      int remaining = available - acquires;
      if (remaining < 0 || compareAndSetState(available, remaining))
        return remaining;
    }
  }
}

标签:令牌,int,Sync,final,源码,线程,阅读,Semaphore,remaining
From: https://www.cnblogs.com/nosae/p/17999193

相关文章

  • 一站式企事业内部培训考学平台源码及功能剖析,在线移动培训考学平台,企业版抖音
    企业培训考学知识库管理系统是一个综合性的平台,用于支持企业的培训和考试需求。1.文档管理及在线预览:1.系统支持上传各种类型的文档,如Word、PDF、PPT、Excel等。2.用户可以直接在线预览这些文档,无需下载。3.对于视频格式的资料,系统也提供了在线播放的功能。2.在线考试与试题......
  • 阅读笔记11
    《梦断代码》讲述了技术与人性的冲突、社会变革与人际关系、对技术乌托邦的反思、游戏与现实的碰撞、人性的探索、以及如何看待科技行业这几个方面。技术与人性的冲突是将技术与人性之间的冲突作为主要主题,探讨了信息时代下技术发展对人类生活的影响。小说中提到了技术进步所带来......
  • 阅读笔记22
    《梦断代码》一书让我有很深的思考和反思。这本小说给了我一个科技发展对人类社会和个体生活产生深远影响的想象空间。它揭示了技术与人性之间的冲突和张力。尽管技术的发展带来了无数便利和可能性,但在追逐技术进步的过程中,人类也付出了很多代价,例如个人隐私的侵犯、人际关系的疏......
  • 阅读笔记
    《人月神话》是一本由弗雷德里克·布鲁克斯所著的软件工程经典书籍,读完我受益匪浅。布鲁克斯提出,项目管理不仅是一门科学,更是一门艺术。项目经理需要具备良好的技术能力,同时也要有卓越的人际关系和沟通能力。他还提出“人月神话”的概念,即增加人力资源并不能加速项目进度。一味的......
  • MyBatis 源码系列:MyBatis 解析配置文件、二级缓存、SQL
    解析全局配置文件启动流程分析Stringresource="mybatis-config.xml";//将XML配置文件构建为Configuration配置类reader=Resources.getResourceAsReader(resource);//通过加载配置文件流构建一个SqlSessionFactoryDefaultSqlSessionFactorySqlSessionFactorysqlMapp......
  • 从源码到成功经营:连锁餐饮管理系统的开发实践
    连锁餐饮业更是需要精密的系统来统一管理多个分店的运营,提高效益并确保一致的服务标准。所以,本篇文章小编将为大家讲述如何开发连锁餐饮管理系统,希望对您有一定的启发。一、系统设计与架构首先,成功的连锁餐饮管理系统源码需要建立在坚实的系统设计与架构基础之上。系统的设计应考虑......
  • CyclicBarrier源码阅读
    目录简介代码分析成员变量方法参考链接本人的源码阅读主要聚焦于类的使用场景,一般只在java层面进行分析,没有深入到一些native方法的实现。并且由于知识储备不完整,很可能出现疏漏甚至是谬误,欢迎指出共同学习本文基于corretto-17.0.9源码,参考本文时请打开相应的源码对照,否则你会......
  • Java开发的SRM供应商、在线询价、招投标采购一体化系统源码功能解析
    前言:随着全球化和信息化的发展,企业采购管理面临越来越多的挑战。传统的采购方式往往涉及到多个繁琐的步骤,包括供应商筛选、询价、招投标等,这些过程不仅耗时,而且容易出错。为了解决这些问题,供应商、询价、招投标一体化系统应运而生。该系统通过集成供应商管理、询价管理、招投标......
  • zookeeper源码(07)leader、follower和observer
    Leader构造方法publicLeader(QuorumPeerself,LeaderZooKeeperServerzk)throwsIOException{this.self=self;this.proposalStats=newBufferStats();//获取节点间通信地址Set<InetSocketAddress>addresses;if(self.getQuorumListenOnAllI......
  • A025 《极限挑战》编程 源码
    一、课程介绍本节课将利用所学习的知识,制作一个空投物资的动画效果。二、重难点解析whileTruewhileTrue:...当while循环中的代码执行到最后一行后,又会跳转到while循环处开始重新执行下一次循环。获取画笔坐标通过xcor()可以获取到画笔的x坐标值,通过ycor()可以获取......