AbstractQueuedSynchronizer文档翻译

2023-12-24 19:38

本文主要是介绍AbstractQueuedSynchronizer文档翻译,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

   一、概述 

        提供一个框架,以实现依赖于先进先出(FIFO)等待队列的阻塞锁和相关同步器(信号量,事件等)。此类旨在为大多数依赖单个原子int值表示状态的同步器提供有用的基础。子类必须定义更改此状态的受保护方法,并且定义该状态对于获取或释放此对象而言意味着什么。鉴于这些,此类中的其他方法将执行所有排队和阻塞机制。子类可以维护其他状态字段,但只是为了获得同步而只追踪使用 getState()、setState(int) 和 compareAndSetState(int, int) 方法来操作以原子方式更新的 int 值。

       子类应定义为用于实现其所在类的同步属性的非公共内部帮助器类。AbstractQueuedSynchronizer没有实现任何同步接口。相反,它定义了acquireInterruptible之类的方法,可以通过具体的锁和相关的同步器适当地调用这些方法以实现其公共方法。

        此类支持默认的exclusive独占模式和shared共享模式之一。当以独占方式进行获取时,其他线程尝试进行的获取将无法成功。由多个线程获取的共享模式可能(但不一定)成功。该类不理解这些区别,只是从机械意义上说,当共享模式获取成功时,下一个等待线程(如果存在)也必须确定它是否也可以获取。在不同模式下等待的线程共享相同的FIFO队列。通常,实现子类仅支持这些模式之一,但两种模式都可以在ReadWriteLock 中发挥作用。仅支持排他或仅共享模式的子类无需定义支持未使用模式的方法。

       此类定义了一个嵌套的ConditionObject类,可由支持独占模式的子类用作Condition实现,isHeldExclusively报告是否相对于当前线程专有地保留同步,使用当前 getState 值调用 release(int) 方法则可以完全释放此对象;如果给定保存的状态值,那么 acquire(int) 方法可以将此对象最终恢复为它以前获取的状态。否则,没有别的AbstractQueuedSynchronizer方法会创建这样的条件,因此,如果无法满足此约束,则不要使用它。AbstractQueuedSynchronizer.ConditionObject 的行为当然取决于其同步器实现的语义。

       此类提供了内部队列的检查,检测和监视方法,还为 condition 对象提供了类似方法。。可以根据需要使用用于其同步机制的 AbstractQueuedSynchronizer 将这些方法导出到类中。

      此类的序列化仅存储基础原子整数维护状态,因此反序列化的对象具有空线程队列。需要序列化性的典型子类将定义一个readObject方法,该方法可在反序列化时将其恢复为已知的初始状态。

二、用法

        要将此类用作同步器的基础,需要适当地重新定义以下方法,这是通过使用 getState()、setState(int) 和/或 compareAndSetState(int,int) 方法来检查和/或修改同步状态来实现的:

  1. tryAcquire
  2. tryRelease
  3. tryAcquireShared
  4. tryReleaseShared
  5. isHeldExclusively

       默认情况下,这些方法中的每一个都会引发 UnsupportedOperationException。这些方法的实现必须在内部是线程安全的,并且通常应简短且不阻塞。定义这些方法是使用此类的唯一 受支持的方式。所有其他方法都声明为final,因为它们不能独立变化。

        您可能还会发现从AbstractOwnableSynchronizer继承的方法对于跟踪拥有独占同步器的线程很有用。鼓励您使用它们,这将启用监视和诊断工具,以帮助用户确定哪些线程持有锁。

       即使此类基于内部FIFO队列,它也不会自动执行FIFO获取策略。独占同步的核心采用以下形式:(共享模式相似,但可能涉及级联信号)

  Acquire:

     //获取失败
      while (!tryAcquire(arg)) {

         如果线程尚未排队,则将其加入队列
         可能阻塞当前线程;
      }
 
  Release:
      if (tryRelease(arg))

          取消第一个排队线程的阻塞

 

      因为要在加入队列之前检查线程的获取状况,因此新获取线程可能会在被阻塞和排队的其他线程之前插入。但是,如果需要,您可以定义 tryAcquire和/或 tryAcquireShared来通过内部调用一种或多种检查方法来禁用插入,从而提供公平 FIFO获取顺序。特别是,如果hasQueuedPredecessors(一种专门为公平同步器设计的方法)返回 true,则大多数公平同步器都可以定义tryAcquire返回 false。其他变化是可能的。

       对于默认插入(也称为greedy(贪婪),renouncement(拒绝)和 convoy-avoidance(避开车队))策略,吞吐量和可伸缩性通常最高。尽管不能保证这是公平的或是无偏向的,但允许更早加入队列的线程先于更迟加入队列的线程再次争用资源,并且相对于传入的线程,每个参与再争用的线程都有平等的成功机会。此外,尽管从一般意义上说,获取并非“自旋”,它们可以在阻塞之前对用其他计算所使用的 tryAcquire 执行多次调用。如果仅短暂地保持排他同步时,这为自旋提供了最大的好处,但不是这种情况时,也不会带来很多负担。如果需要这样做,那么可以使用“快速路径”检查来先行调用 acquire 方法来扩充此功能,如果可能不需要争用同步器,则只能通过预先检查 hasContended() 和/或 hasQueuedThreads() 来确认这一点。

      通过特殊化其同步器的使用范围,此类为部分同步化提供了一个有效且可伸缩的基础,同步器可以依赖于 int 型的 state、acquire 和 release 参数,以及一个内部的 FIFO 等待队列。这些还不够的时候,可以使用 atomic 类、自己的定制 Queue 类和 LockSupport 阻塞支持,从更低级别构建同步器。

三、样例

       这是一个不可重入的互斥锁定类,使用值0表示解锁状态,使用值1表示锁定状态。尽管不可重入锁并不严格要求记录当前所有者线程,但无论如何,此类会这样做,以使使用情况更易于监视。它还支持条件并公开一种检测方法

class Mutex implements Lock, java.io.Serializable {/*** 内部帮助器类*/private static class Sync extends AbstractQueuedSynchronizer {// 记录是否持有锁@Overrideprotected boolean isHeldExclusively() {return getState() == 1;}// 获取锁如果state值为0@Overridepublic boolean tryAcquire(int acquires) {assert acquires == 1; // Otherwise unusedif (compareAndSetState(0, 1)) {setExclusiveOwnerThread(Thread.currentThread());return true;}return false;}//释放锁通过设置state为0@Overrideprotected boolean tryRelease(int releases) {assert releases == 1; // Otherwise unusedif (getState() == 0) {throw new IllegalMonitorStateException();}setExclusiveOwnerThread(null);setState(0);return true;}/*** Provides a Condition*/Condition newCondition() {return new ConditionObject();}/*** Deserializes properly*/private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {s.defaultReadObject();setState(0); // reset to unlocked state}}/*** 同步对象完成所有艰苦的工作。我们只是期待它*/private final Sync sync = new Sync();@Overridepublic void lock() {sync.acquire(1);}@Overridepublic boolean tryLock() {return sync.tryAcquire(1);}@Overridepublic void unlock() {sync.release(1);}@Overridepublic Condition newCondition() {return sync.newCondition();}public boolean isLocked() {return sync.isHeldExclusively();}public boolean hasQueuedThreads() {return sync.hasQueuedThreads();}@Overridepublic void lockInterruptibly() throws InterruptedException {sync.acquireInterruptibly(1);}@Overridepublic boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException {return sync.tryAcquireNanos(1, unit.toNanos(timeout));}
}

      这是一个类似于CountDownLatch的闩锁类,除了只需要触发单个 signal 之外。由于闩锁是非排他性的,因此它使用shared获取和释放方法

class BooleanLatch {private static class Sync extends AbstractQueuedSynchronizer {boolean isSignalled() {return getState() != 0;}@Overrideprotected int tryAcquireShared(int ignore) {return isSignalled() ? 1 : -1;}@Overrideprotected boolean tryReleaseShared(int ignore) {setState(1);return true;}}private final Sync sync = new Sync();public boolean isSignalled() {return sync.isSignalled();}public void signal() {sync.releaseShared(1);}public void await() throws InterruptedException {sync.acquireSharedInterruptibly(1);}
}

 

 

这篇关于AbstractQueuedSynchronizer文档翻译的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/532897

相关文章

Java利用docx4j+Freemarker生成word文档

《Java利用docx4j+Freemarker生成word文档》这篇文章主要为大家详细介绍了Java如何利用docx4j+Freemarker生成word文档,文中的示例代码讲解详细,感兴趣的小伙伴... 目录技术方案maven依赖创建模板文件实现代码技术方案Java 1.8 + docx4j + Fr

使用C#代码在PDF文档中添加、删除和替换图片

《使用C#代码在PDF文档中添加、删除和替换图片》在当今数字化文档处理场景中,动态操作PDF文档中的图像已成为企业级应用开发的核心需求之一,本文将介绍如何在.NET平台使用C#代码在PDF文档中添加、... 目录引言用C#添加图片到PDF文档用C#删除PDF文档中的图片用C#替换PDF文档中的图片引言在当

详解C#如何提取PDF文档中的图片

《详解C#如何提取PDF文档中的图片》提取图片可以将这些图像资源进行单独保存,方便后续在不同的项目中使用,下面我们就来看看如何使用C#通过代码从PDF文档中提取图片吧... 当 PDF 文件中包含有价值的图片,如艺术画作、设计素材、报告图表等,提取图片可以将这些图像资源进行单独保存,方便后续在不同的项目中使

Python实现合并与拆分多个PDF文档中的指定页

《Python实现合并与拆分多个PDF文档中的指定页》这篇文章主要为大家详细介绍了如何使用Python实现将多个PDF文档中的指定页合并生成新的PDF以及拆分PDF,感兴趣的小伙伴可以参考一下... 安装所需要的库pip install PyPDF2 -i https://pypi.tuna.tsingh

Python批量调整Word文档中的字体、段落间距及格式

《Python批量调整Word文档中的字体、段落间距及格式》这篇文章主要为大家详细介绍了如何使用Python的docx库来批量处理Word文档,包括设置首行缩进、字体、字号、行间距、段落对齐方式等,需... 目录关键代码一级标题设置  正文设置完整代码运行结果最近关于批处理格式的问题我查了很多资料,但是都没

Python自动化Office文档处理全攻略

《Python自动化Office文档处理全攻略》在日常办公中,处理Word、Excel和PDF等Office文档是再常见不过的任务,手动操作这些文档不仅耗时耗力,还容易出错,幸运的是,Python提供... 目录一、自动化处理Word文档1. 安装python-docx库2. 读取Word文档内容3. 修改

使用Python快速实现链接转word文档

《使用Python快速实现链接转word文档》这篇文章主要为大家详细介绍了如何使用Python快速实现链接转word文档功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 演示代码展示from newspaper import Articlefrom docx import

浅析如何使用Swagger生成带权限控制的API文档

《浅析如何使用Swagger生成带权限控制的API文档》当涉及到权限控制时,如何生成既安全又详细的API文档就成了一个关键问题,所以这篇文章小编就来和大家好好聊聊如何用Swagger来生成带有... 目录准备工作配置 Swagger权限控制给 API 加上权限注解查看文档注意事项在咱们的开发工作里,API

SpringBoot3集成swagger文档的使用方法

《SpringBoot3集成swagger文档的使用方法》本文介绍了Swagger的诞生背景、主要功能以及如何在SpringBoot3中集成Swagger文档,Swagger可以帮助自动生成API文档... 目录一、前言1. API 文档自动生成2. 交互式 API 测试3. API 设计和开发协作二、使用

基于C#实现将图片转换为PDF文档

《基于C#实现将图片转换为PDF文档》将图片(JPG、PNG)转换为PDF文件可以帮助我们更好地保存和分享图片,所以本文将介绍如何使用C#将JPG/PNG图片转换为PDF文档,需要的可以参考下... 目录介绍C# 将单张图片转换为PDF文档C# 将多张图片转换到一个PDF文档介绍将图片(JPG、PNG)转