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

相关文章

使用EasyPoi快速导出Word文档功能的实现步骤

《使用EasyPoi快速导出Word文档功能的实现步骤》EasyPoi是一个基于ApachePOI的开源Java工具库,旨在简化Excel和Word文档的操作,本文将详细介绍如何使用EasyPoi快速... 目录一、准备工作1、引入依赖二、准备好一个word模版文件三、编写导出方法的工具类四、在Export

利用Python操作Word文档页码的实际应用

《利用Python操作Word文档页码的实际应用》在撰写长篇文档时,经常需要将文档分成多个节,每个节都需要单独的页码,下面:本文主要介绍利用Python操作Word文档页码的相关资料,文中通过代码... 目录需求:文档详情:要求:该程序的功能是:总结需求:一次性处理24个文档的页码。文档详情:1、每个

C++读写word文档(.docx)DuckX库的使用详解

《C++读写word文档(.docx)DuckX库的使用详解》DuckX是C++库,用于创建/编辑.docx文件,支持读取文档、添加段落/片段、编辑表格,解决中文乱码需更改编码方案,进阶功能含文本替换... 目录一、基本用法1. 读取文档3. 添加段落4. 添加片段3. 编辑表格二、进阶用法1. 文本替换2

Python实现自动化删除Word文档超链接的实用技巧

《Python实现自动化删除Word文档超链接的实用技巧》在日常工作中,我们经常需要处理各种Word文档,本文将深入探讨如何利用Python,特别是借助一个功能强大的库,高效移除Word文档中的超链接... 目录为什么需要移除Word文档超链接准备工作:环境搭建与库安装核心实现:使用python移除超链接的

C#实现一键批量合并PDF文档

《C#实现一键批量合并PDF文档》这篇文章主要为大家详细介绍了如何使用C#实现一键批量合并PDF文档功能,文中的示例代码简洁易懂,感兴趣的小伙伴可以跟随小编一起学习一下... 目录前言效果展示功能实现1、添加文件2、文件分组(书签)3、定义页码范围4、自定义显示5、定义页面尺寸6、PDF批量合并7、其他方法

Java实现在Word文档中添加文本水印和图片水印的操作指南

《Java实现在Word文档中添加文本水印和图片水印的操作指南》在当今数字时代,文档的自动化处理与安全防护变得尤为重要,无论是为了保护版权、推广品牌,还是为了在文档中加入特定的标识,为Word文档添加... 目录引言Spire.Doc for Java:高效Word文档处理的利器代码实战:使用Java为Wo

使用Python实现Word文档的自动化对比方案

《使用Python实现Word文档的自动化对比方案》我们经常需要比较两个Word文档的版本差异,无论是合同修订、论文修改还是代码文档更新,人工比对不仅效率低下,还容易遗漏关键改动,下面通过一个实际案例... 目录引言一、使用python-docx库解析文档结构二、使用difflib进行差异比对三、高级对比方

Python自动化处理PDF文档的操作完整指南

《Python自动化处理PDF文档的操作完整指南》在办公自动化中,PDF文档处理是一项常见需求,本文将介绍如何使用Python实现PDF文档的自动化处理,感兴趣的小伙伴可以跟随小编一起学习一下... 目录使用pymupdf读写PDF文件基本概念安装pymupdf提取文本内容提取图像添加水印使用pdfplum

Python从Word文档中提取图片并生成PPT的操作代码

《Python从Word文档中提取图片并生成PPT的操作代码》在日常办公场景中,我们经常需要从Word文档中提取图片,并将这些图片整理到PowerPoint幻灯片中,手动完成这一任务既耗时又容易出错,... 目录引言背景与需求解决方案概述代码解析代码核心逻辑说明总结引言在日常办公场景中,我们经常需要从 W

C#高效实现Word文档内容查找与替换的6种方法

《C#高效实现Word文档内容查找与替换的6种方法》在日常文档处理工作中,尤其是面对大型Word文档时,手动查找、替换文本往往既耗时又容易出错,本文整理了C#查找与替换Word内容的6种方法,大家可以... 目录环境准备方法一:查找文本并替换为新文本方法二:使用正则表达式查找并替换文本方法三:将文本替换为图