news 2026/5/10 12:43:19

Java同步器的介绍

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Java同步器的介绍

同步器(AQS)的设计是基于模板方法模式的,使用者(指的是自定义同步器)需要继承同步器AQS)并重写AQS指定的方法,随后将同步器(自定义的同步器)组合在自定义同步组件的实现中,并调用同步器(AQS)提供的模板方法,而这些模板方法将会调用使用者(自定义同步器)重写的方法。自定义同步器重写同步器(AQS)指定的方法时(需要同步状态的配合),会用到同步器(AQS)提供的如下3个方法来访问或修改同步状态。

·getState():获取当前同步状态。

·setState(int newState):设置当前同步状态。

·compareAndSetState(int expect,int update):使用CAS设置当前状态,该方法能够保证状态设置的原子性。

根据上面这段文字,对如何构造一个自定义的同步组件总结如下:

1》定义一个继承AQS同步器的静态的私有的内部类;

2》该内部类要重写AQS中指定的方法tryAcquire()和tryRelease()方法;

3》该自定义同步组件调用AQS中提供的模板方法,而这些模板方法将会调用使用者(自定义同步器)重写的方法。

下面是一个例子:独占锁Mutex是一个自定义同步组件,它在同一时刻只允许一个线程占有锁。Mutex中定义了一个静态内部类,该内部类继承了同步器(AQS)并实现了独占式获取和释放同步状态。在tryAcquire(int acquires)方法中,如果经过CAS设置成功(同步状态设置为1),则代表获取了同步状态,而在tryRelease(int releases)方法中只是将同步状态重置为0。用户使用Mutex时并不会直接和内部同步器的实现打交道,而是调用Mutex提供的方法,在Mutex的实现中,以获取锁的lock()方法为例,只需要在方法实现中调用同步器的模板方法acquire(int args)即可,当前线程调用该方法获取同步状态失败后会被加入到同步队列中等待,这样就大大降低了实现一个可靠自定义同步组件的门槛。

import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.AbstractQueuedSynchronizer; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; /** * 自定义一个同步组件(例如这里的Mutex),首先定义一个静态内部私有类,且该类要继承AbstractQueuedSynchronizer这个抽象类 * 重写同步器指定的方法:此时需要同步状态的配合,会用到同步器提供的如下3个方法来访问或修改同步状态。 getState():获取当前同步状态。 * setState(int newState):设置当前同步状态。 compareAndSetState(int expect,int * update):使用CAS设置当前状态,该方法能够保证状态设置的原子性。 */ public class Mutex implements Lock { // 静态内部类,自定义一个同步器。注意:Mutex是同步器组件 private static class Sync extends AbstractQueuedSynchronizer { private static final long serialVersionUID = -4387327721959839431L; // 是否处于占用状态,getState()来自父类 protected boolean isHeldExclusively() { return getState() == 1; } /* 当状态为0(acquires=0)的时候获取锁 重写父类中的方法 * @see java.util.concurrent.locks.AbstractQueuedSynchronizer#tryAcquire(int) * 独占式获取同步状态,实现该方法需要查询当前状态并判断同步状态是否符合预期,然 后在进行CAS设置同步状态 */ public boolean tryAcquire(int acquires) { assert acquires == 1; // Otherwise unused // 获取锁成功后将状态置为1,这样其他线程就不能获取了 if (compareAndSetState(0, 1)) { // 设置当前线程为该锁的拥有者 setExclusiveOwnerThread(Thread.currentThread()); return true; } return false; } // 释放锁,将状态设置为0 protected boolean tryRelease(int releases) { assert releases == 1; // Otherwise unused if (getState() == 0) throw new IllegalMonitorStateException(); // 将该锁设置为不为任何线程所拥有 setExclusiveOwnerThread(null); // 设置状态为0 setState(0); return true; } // 返回一个Condition,每个condition都包含了一个condition队列 Condition newCondition() { return new ConditionObject(); } } // 仅需要将操作代理到Sync(使用Sync完成同步加锁功能)上即可 private final Sync sync = new Sync(); // 获取锁,调用父类中的方法acquire()方法 public void lock() { sync.acquire(1); } // 尝试获取锁 public boolean tryLock() { return sync.tryAcquire(1); } // 释放锁 public void unlock() { sync.release(1); } public Condition newCondition() { return sync.newCondition(); } // 判断锁是否处于占用状态 public boolean isLocked() { return sync.isHeldExclusively(); } public boolean hasQueuedThreads() { return sync.hasQueuedThreads(); } public void lockInterruptibly() throws InterruptedException { sync.acquireInterruptibly(1); } public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException{ return sync.tryAcquireNanos(1, unit.toNanos(timeout)); } }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/30 22:37:57

Java队列同步器的实现分析

接下来将从实现角度分析同步器是如何完成线程同步的,主要包括:同步队列、独占式同步状态获取与释放、共享式同步状态获取与释放以及超时获取同步状态等同步器的核心数据结构与模板方法。一、同步队列同步器依赖内部的同步队列(一个FIFO双向队…

作者头像 李华
网站建设 2026/5/1 17:00:11

金融产品介绍视频标准化:HeyGem统一品牌形象输出

金融产品介绍视频标准化:HeyGem统一品牌形象输出 在银行网点、手机App或客户经理的讲解屏前,你是否注意到——不同分支机构对同一款理财产品的解说,语速不一、重点各异,甚至口型与语音错位?这种“千人千面”的表达方式…

作者头像 李华
网站建设 2026/5/3 5:48:23

xhEditor word粘贴支持表格和列表

(扶了扶眼镜,敲着机械键盘开始码字) 各位老铁,作为山西网络安全专业的"码农",今天给大家表演一个"如何在预算99元内实现Word内容一键粘贴"的绝活。首先,咱们得给xhEditor这个老编辑器…

作者头像 李华
网站建设 2026/5/1 6:10:48

小目标检测在热红外域的挑战 _ - 无可见光条件下基于热特征的显著性建模 _ - - 夜间智能监控系统开发 如何训练无人机视角行人 _ 车辆检测与显著性分割的热红外数据集

面向无人机视角行人 / 车辆检测与显著性分割的热红外数据集 数据由 DJI M600Pro 无人机搭载 FLIR Vue Pro 热像仪在白天与夜间采集,专门解决“无人机视角下缺乏行人和车辆热红外公开数据集”的问题,并提供目标检测和显著性检测所需的像素级标注。 数…

作者头像 李华
网站建设 2026/5/8 0:02:35

爱沙尼亚语数字政府服务:公务员数字人讲解办事流程

爱沙尼亚语数字政府服务:公务员数字人讲解办事流程 在爱沙尼亚,一个不到140万人口的国家,99%的政务服务已实现在线办理。居民可以在几分钟内完成报税、注册公司甚至跨境业务申报——这一切都建立在“电子公民”(e-Residency&#…

作者头像 李华
网站建设 2026/5/9 4:01:45

马耳他语地中海饮食推广:厨师数字人推荐健康食谱

马耳他语地中海饮食推广:厨师数字人推荐健康食谱 —— 基于 HeyGem 数字人视频生成系统的技术实现 在马耳他,一种被联合国教科文组织列为非物质文化遗产的地中海饮食文化正面临传播困境:尽管它以橄榄油、新鲜蔬果和鱼类为核心,被誉…

作者头像 李华