当前位置: 首页 > news >正文

利用aqs构建一个自己的公平独占锁

前期回顾

利用aqs构建一个自己的非公平独占锁

本期目标:实现一个公平独占锁

独占:同一时间只有一个线程能获取锁。
公平:线程按照请求顺序(FIFO)获得锁,避免线程“插队”。
基于 AQS:重写 tryAcquire 和 tryRelease 方法。

代码

import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Lock;/*** 基于 AQS 实现的公平独占锁*/
public class FairExclusiveLock implements Lock {// 内部静态类:继承 AQS,实现公平锁逻辑private static class Sync extends AbstractQueuedSynchronizer {private static final long serialVersionUID = 1L;// 是否为公平模式@Overrideprotected boolean isHeldExclusively() {return getExclusiveOwnerThread() == Thread.currentThread();}// 尝试获取锁(公平方式)@Overrideprotected boolean tryAcquire(int acquires) {if (acquires != 1) throw new IllegalArgumentException();// 【核心】检查是否有前驱等待节点(公平性关键)if (hasQueuedPredecessors()) {return false; // 有其他线程在等待,本次获取失败,加入队列}int currentStatus = getState();if (currentStatus == 0) {// 无锁状态,尝试 CAS 获取if (compareAndSetState(0, 1)) {// 设置锁的拥有者setExclusiveOwnerThread(Thread.currentThread());return true;}} else if (getExclusiveOwnerThread() == Thread.currentThread()) {// 已经是当前线程持有锁,支持可重入setState(currentStatus + 1);return true;}return false;}// 尝试释放锁@Overrideprotected boolean tryRelease(int releases) {if (Thread.currentThread() != getExclusiveOwnerThread()) {throw new IllegalMonitorStateException("Not owner");}int nextc = getState() - 1;boolean free = (nextc == 0);if (free) {setExclusiveOwnerThread(null);}setState(nextc);return free;}}// 使用 Sync 实例private final Sync sync = new Sync();// ------------- Lock 接口实现 -------------@Overridepublic void lock() {sync.acquire(1); // 阻塞式获取锁}@Overridepublic void lockInterruptibly() throws InterruptedException {sync.acquireInterruptibly(1);}@Overridepublic boolean tryLock() {return sync.tryAcquire(1);}@Overridepublic boolean tryLock(long time, java.util.concurrent.TimeUnit unit)throws InterruptedException {return sync.tryAcquireNanos(1, unit.toNanos(time));}@Overridepublic void unlock() {sync.release(1); // 释放锁}@Overridepublic java.util.concurrent.Condition newCondition() {return sync.newCondition();}
}

公平性的实现

  • hasQueuedPredecessors():判断当前线程前面是否有其他线程在等待。
  • 如果有,即使锁空闲,也 不立即获取,而是排队等待。
  • 这就是 公平锁 的核心机制。

测试代码

public class FairExclusiveLockTest {private static final FairExclusiveLock lock = new FairExclusiveLock();private static int counter = 0;public static void main(String[] args) throws InterruptedException {Thread[] threads = new Thread[5];for (int i = 0; i < 5; i++) {final int threadId = i;threads[i] = new Thread(() -> {System.out.println("线程 " + threadId + " 尝试获取锁");lock.lock();try {System.out.println("线程 " + threadId + " 获取锁,执行任务...");Thread.sleep(1000); // 模拟工作counter++;System.out.println("线程 " + threadId + " 完成,counter=" + counter);} catch (InterruptedException e) {Thread.currentThread().interrupt();} finally {lock.unlock();}});}// 启动所有线程for (Thread t : threads) t.start();for (Thread t : threads) t.join();System.out.println("最终 counter = " + counter);}
}

输出结果

线程 0 尝试获取锁
线程 1 尝试获取锁
线程 2 尝试获取锁
线程 3 尝试获取锁
线程 4 尝试获取锁
线程 0 获取锁,执行任务...
线程 0 完成,counter=1
线程 1 获取锁,执行任务...
线程 1 完成,counter=2
线程 2 获取锁,执行任务...
...
http://www.dtcms.com/a/554382.html

相关文章:

  • html网站源码下载天眼查官网查询入口
  • 14、做中学 | 初二上期 Golang集合Map
  • 做网站前置审批建设银行北京东四支行网站
  • 合规与体验的平衡:多区域身份验证适配中的模块化架构设计案例
  • 更换网站标题网站设计建设合同
  • 怎么用wordpress 建站工业产品设计效果图
  • DeepSeek-OCR
  • LeeCode 141. 环形链表
  • 网站建设费用说明建设一个网站
  • 博山做网站公司渝中网站建设
  • 孤能子视角:基于“N(EI+N(EI))“路径EIS理论人工智能定义
  • 汝南网站建设网站建设维护工作
  • 网站建设项目内控单公司网站优化外包
  • 西青做网站wordpress 标签修改
  • 网页模板怎么做网站wordpress去视频广告插件
  • 华为云iot消息积压问题
  • 简单网站页面设计制作链接的app的软件有哪些
  • Qt功能QSortFilterProxyModel指南
  • RAPID:基于逆强化学习的无人机视觉导航鲁棒且敏捷规划器
  • 免费个人网站模版ps手机网站 ui
  • 东莞网站优化服务公司建网站龙
  • Rust数据类型(下):复合类型详解
  • 【一阶段分析】文生图提示词笔记
  • 0成本get可信域名:dpdns.org公益域名获取全攻略
  • WordPress建影视站电商品牌推广方案
  • 站长工具关键词南京外贸网站建设案例
  • ESP32-P4-Function-EV-Board例程编译报错解决记录
  • Hierholzer 算法
  • 一文读懂分辨率:从概念到硬件应用,解锁视觉体验新高度
  • ppt图标网站链接怎么做珠海做网站哪间好