深圳网站建设学习网站建设购销合同

news/2025/9/22 15:28:49/文章来源:
深圳网站建设学习,网站建设购销合同,设计企业品牌logo,建设网站免费支持php1 释放锁流程概述 ReentrantLock的unlock()方法不区分公平锁还是非公平锁。 首先调用unlock()方法。 unlock()底层使用的是Sync.release(1)方法 public void unlock() {!-- -- sync.release(1); } release(1)方法会调用tryRelease(1)去尝试解锁。 public fin…1 释放锁流程概述 ReentrantLock的unlock()方法不区分公平锁还是非公平锁。 首先调用unlock()方法。 unlock()底层使用的是Sync.release(1)方法  public void unlock() {!-- --      sync.release(1);  } release(1)方法会调用tryRelease(1)去尝试解锁。 public final boolean release(int arg) {!-- --//尝试释放锁if (tryRelease(arg)) {!-- --Node h head;if (h ! null h.waitStatus ! 0)//如果释放锁成功而且等待队列不为空且有一个以上的等待线程//因为只有下一个线程才能将前一个线程的waitStatus的状态改为-1head表示当前执行的线程//当head不为空且waitStatus 0说明有等待线程初始化了等待队列且将持有锁线程的//等待状态改为了-1必然存在等待线程将队头的第一个唤醒unparkSuccessor(h);return true;}return false;} tryRelease(arg)尝试释放锁 ReservedStackAccessprotected final boolean tryRelease(int releases) {!-- --//释放一次锁就将重入的次数减掉1int c getState() - releases;if (Thread.currentThread() ! getExclusiveOwnerThread())throw new IllegalMonitorStateException();boolean free false;//如果锁得状态为1则表示锁真正被释放了将持有锁的线程置为nullif (c 0) {!-- --free true;setExclusiveOwnerThread(null);}//否则锁依然被持有因为该锁被持锁线程重入了多次setState(c);return free;} 如果tryRelease(释放锁成功且判断等待队列确实有阻塞线程则尝试唤醒 private void unparkSuccessor(Node node) {!-- --//如果等待的线程状态0SIGNAL将其设为0int ws node.waitStatus;if (ws 0)node.compareAndSetWaitStatus(ws, 0);Node s node.next;//找一个符合条件即真正在阻塞睡眠的线程if (s null || s.waitStatus 0) {!-- --s null;for (Node p tail; p ! node p ! null; p p.prev)if (p.waitStatus 0)s p;}//找到后将其唤醒。有个疑问头节点不变化嘛if (s ! null)LockSupport.unpark(s.thread);} 回答自己的疑问为啥没有操作头节点呢这是因为唤醒阻塞的第一个线程后它会重新去获取锁而不是直接将锁分配给它。 final boolean acquireQueued(final Node node, int arg) {!-- --boolean interrupted false;try {!-- --for (;;) {!-- --final Node p node.predecessor();if (p head tryAcquire(arg)) {!-- --setHead(node);p.next null; // help GCreturn interrupted;}if (shouldParkAfterFailedAcquire(p, node))//从此处被唤醒后重新进行循环尝试去争抢锁如果没抢到则继续阻塞(非公平的时候)//当刚被唤醒循环一次此时phead同时如果tryAcquire(1)去获得锁//如果获得成功将自己设置为head//如果获得锁失败则自己再自旋一次(因为在释放锁的时候head的ws又重置为0了).//如果还是失败则自己再次park()睡眠interrupted | parkAndCheckInterrupt();}} catch (Throwable t) {!-- --cancelAcquire(node);if (interrupted)selfInterrupt();throw t;}} 2 释放锁源码分析 public void unlock() { // 释放锁资源不分为公平锁和非公平锁都是一个sync对象 sync.release(1); } // 释放锁的核心流程 public final boolean release(int arg) { // 核心释放锁资源的操作之一 if (tryRelease(arg)) { // 如果锁已经释放掉了走这个逻辑 Node h head; // h不为null说明有排队的录课时估计脑袋蒙圈圈。 // 如果h的状态不为0为-1说明后面有排队的Node并且线程已经挂起了。 if (h ! null h.waitStatus ! 0)// 唤醒排队的线程 unparkSuccessor(h); return true; } return false; } // ReentrantLock释放锁资源操作 protected final boolean tryRelease(int releases) { // 拿到state - 1并没有赋值给state int c getState() - releases; // 判断当前持有锁的线程是否是当前线程如果不是直接抛出异常 if (Thread.currentThread() ! getExclusiveOwnerThread()) throw new IllegalMonitorStateException(); // free代表当前锁资源是否释放干净了。 boolean free false; if (c 0) { // 如果state - 1后的值为0代表释放干净了。 free true; // 将持有锁的线程置位null setExclusiveOwnerThread(null); } // 将c设置给state setState(c); // 锁资源释放干净返回true否则返回false return free; } // 唤醒后面排队的Node private void unparkSuccessor(Node node) { // 拿到头节点状态 int ws node.waitStatus; if (ws 0) // 先基于CAS将节点状态从-1改为0 compareAndSetWaitStatus(node, ws, 0); // 拿到头节点的后续节点。 Node s node.next; // 如果后续节点为null或者后续节点的状态为1代表节点取消了。 if (s null || s.waitStatus 0) { s null; // 如果后续节点为null或者后续节点状态为取消状态从后往前找到一个有效节点环境 for (Node t tail; t ! null t ! node; t t.prev) // 从后往前找到状态小于等于0的节点 // 找到离head最新的有效节点并赋值给s if (t.waitStatus 0) s t; } // 只要找到了这个需要被唤醒的节点执行unpark唤醒 if (s ! null) LockSupport.unpark(s.thread); } 3 AQS常见的问题 3.1 AQS中为什么要有一个虚拟的head节点 因为AQS提供了ReentrantLock的基本实现而在ReentrantLock释放锁资源时需要去考虑是否需要执行unparkSuccessor方法去唤醒后继节点。         因为Node中存在waitStatus的状态默认情况下状态为0如果当前节点的后继节点线程挂起了那么就将当前节点的状态设置为-1。这个-1状态的出现是为了避免重复唤醒或者释放资源的问题。         因为AQS中排队的Node中的线程如果挂起了是无法自动唤醒的。需要释放锁或者释放资源后再被释放的线程去唤醒挂起的线程。 因为唤醒节点需要从整个AQS双向链表中找到离head最近的有效节点去唤醒。而这个找离head最近的Node可能需要遍历整个双向链表。如果AQS中没有挂起的线程代表不需要去遍历AQS双向链表去找离head最近的有效节点。为了避免出现不必要的循环链表操作提供了一个-1的状态。如果只有一个Node进入到AQS中排队所以发现如果是第一个Node进来他必须先初始化一个虚拟的head节点作为头来监控后继节点中是否有挂起的线程。 3. 2 AQS中为什么选择使用双向链表而不是单向链表 首先AQS中一般是存放没有获取到资源的Node而在竞争锁资源时ReentrantLock提供了一个方法lockInterruptibly方法也就是线程在竞争锁资源的排队途中允许中断。中断后会执行cancelAcquire方法从而将当前节点状态置位1并且从AQS队列中移除掉。如果采用单向链表当前节点只能按到后继或者前继节点这样是无法将前继节点指向后继节点的需要遍历整个 AQS从头或者从尾去找。单向链表在移除AQS中排队的Node时成本很高。         当前在唤醒后继节点时如果是单向链表也会出问题因为节点插入方式的问题导致只能单向的去找有效节点去唤醒从而造成很多次无效的遍历操作如果是双向链表就可以解决这个问题。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

个人网站做项目万能软文模板

文章目录 什么是SSH协议?SSH为何是安全的?SSH由哪些组件构成?SSH可以帮助实现的功能SSH的工作原理SSH的历史版本常用的SSH工具有哪些SSH配置案例参考Windows 安装SSHUbuntu系统SSH配置Cisco Switch SSH配置华为Switch SSH配置 客户端启用SSH连…

比较好设计网站wordpress 按钮美化

Vue.js 是一套构建用户界面的渐进式框架。只关注视图层, 采用自底向上增量开发的设计。 目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。Vue 学习起来非常简单。 目录 常用的vue.js版本及方法 学习vue之前需要掌握基础html+css+javaScript知识。 比如: …

python 网站开发书籍wordpress百度熊掌号

牛年跳槽季如火如荼,敏锐点的小伙伴儿应该都留意到了,BAT新年都在招聘.NET。2020年11月份发布.NET5统一了七大应用方向,.NET6的2个预览版已经把Blazor升级、跨平台UI方案MAUI、CLR性能优化等都放出来了,.NET前景充满想象&#xff…

桂林做网站建设的公司电子商务网站建设与管理总结

SCI论文作图规范包括以下几个方面: 一、图片格式 SCI论文通常接受的图片格式包括TIFF、EPS和PDF等。其中,TIFF格式是一种高质量的图像格式,适用于需要高分辨率和颜色准确性的图片;EPS格式是一种矢量图形格式,适用于需…

做网站的例子建设网站的五个步骤

👨‍🎓作者简介:一位大四、研0学生,正在努力准备大四暑假的实习 🌌上期文章:Redis:原理速成项目实战——Redis实战4(解决Redis缓存穿透、雪崩、击穿) 📚订阅专…

用ida插件快速审计函数调用

如果xref窗口会显示调用的伪代码,也许就不会有今天...前言 我又要在前言絮絮叨叨一下我是为什么要做这个小插件的了...就不看 在审查程序的漏洞的时候,我们可能会重点关注那么几个重点函数的调用:system肯定是重中之…

【ACM独立出版|往届已EI、Scopus检索|合作SSCI】第二届数字经济与计算机科学国际学术会议(DECS 2025)

第二届数字经济与计算机科学国际学术会议(DECS 2025)将于2025年10月17日至10月19日在中国武汉召开。本次会议旨在汇聚来自全球的学者、研究人员和业界专家,共同探讨数字经济与计算机科学领域的最新发展与应用。随着…

schematool -initSchema -dbType mysql

hive启动之前一定要用这条命令初始化

叶县红色家园网站建设公众号登陆

文章开始之前,建议安装一个显示网速的插件,不然你不知道到底有没有下载,也让生活有一点盼头 1.因为众所周知的原因(我dang的行为真的是让人失望),先更换一下ruby镜像源 $ gem sources --remove https://rub…

PostgreSQL 全表 count 优化实践:从 SeqScan 痛点分析到 heapam 改进与性能突破

本文整理自 IvorySQL 2025 生态大会暨 PostgreSQL 高峰论坛的演讲分享,演讲嘉宾:权宗亮。本文主要包括以下三部分:SeqScan 现状 heapam 改进 全表计数SeqScan 现状 我们使用了一个稍宽的 SeqScan 表,包含约 10-20 …

微信微网站建设平台wordpress改变友情链接顺序

文学迷 > 玄幻魔法 > 天命神相 > 第一千六百零七章 鸿蒙紫气,成圣之机 (上)第一千六百零七章 鸿蒙紫气,成圣之机功德金身只要达到了八十一重天,大圆满的境界,实力堪混元大罗级别的圣人,这听起来确实是一件吊炸…

逸阳网站建设的目标完整的网站优化放啊

文章目录 前言一、pandas是什么?二、使用步骤 1.引入库2.读入数据总结 一. VRRP概述 VRRP---虚拟路由器冗余协议 VRRP(Virtual Router Redundancy Protocol)是一种用于在多个路由器之间创建虚拟路由器的协议。 VRRP使用了一系列协议来实现路…

学习做网站的孛校呼和浩特网站建设费用

更新:使用 滏阳河边捉蚯蚓 https://zhuanlan.zhihu.com/p/41297136上获取系统PDF文件和zotero.sqlite文件的代码,在此感谢!在zotero的library中删除参考文献条目后,有时PDF不会同步删除,尤甚是安装了zotfile插件后&…

登建设厅锁子的是哪个网站sharepoint 网站开发

这里 Allocation failed - JavaScript heap out of memory JavaScript堆内存不足,我们都知道 Node 是基于V8引擎,在一般的后端开发语言中,在基本的内存使用上没有什么限制,但是我去查阅了相关的资料才发现,在 Node 中通…

Lightroom Classic 2025:精细调控,呈现完美画质,专业级数字照片管理与后期处理全解析

Lightroom Classic 2024是一款由Adobe开发的数字照片后期处理软件,它为摄影师和摄影爱好者提供了一个全面、高效的后期处理平台。通过Lightroom Classic 2024,用户可以轻松地对数字照片进行各种调整和修饰,以实现最…

负载分析和排查五

负载分析和排查五明白 ✅ 我不会乱改行、不省略、不简化,而是在你提供的表格基础上补充更详细的内容:包括 问题原因分析 → 判断依据 → perf 排查命令 → 优化方向(C 语言/系统示例)。保证格式对齐,逐行完善。下…

管理网站建设源代码程序做网站用啥软件

题目描述 题目链接:https://leetcode.cn/problems/merge-two-sorted-lists/description/ 思路 两个链表都是升序链表,新建一个链表,引入伪头节点作为辅助节点,将各节点添加到伪节点之后,再用一个cur节点指向新链表的…

langfuse从v2.70.1升级到V3.110(异机升级+数据迁移)

环境:Os:Centos 7langfuse:升级前版本:V2.70.1升级后版本:V3.110 说明:v3部署在新机器,我们需要将v2下的postgresql外挂的数据目录文件拷贝到v3下的外挂数据目录说明:yaml资源清单文件直接下载,尽量不要复制粘贴,避免…

宿州医疗网站建设设计一个学院网站

后面我们写代码时,写完可能会出现没有执行权限什么的,所以我们要知道文件都有哪些权限和类型。 首先 就像我们之前目录结构图里面有个/dev,它就是存放设备文件的,也就是说,哪怕是一个硬件设备,例如打印机啥的&#xf…

20250518_信安一把梭_医院抓取流量

流量分析, 应急响应, 数据统计, 信安一把梭Tags:流量分析, 应急响应, 数据统计, 信安一把梭 0x00. 题目 医院脱库应急处理(医院抓取流量.pcapng)首次发起端口扫描的IP审计流量和日志快速定位扫描次数最多的IP审计流量…