Java并发进阶系列:深度讨论官方关于jdk1.8ConcurrentHashMap的resizeStamp源代码修复逻辑
前言首先给出以下open JDK版本的序号说明和Oracle JDK序号说明(1)对于JDK8或者Java 8即可指代openjdk-8-jdk或者java-1.8.0-openjdk,也可指代Oracle家的Java SE 8或者JDK 8u211 and later(1)对于JDK16或者Java 16即可指代openjdk的JDK 16.0.2 ,也可指代Oracle家的Java SE 16或者 jdk16.0.1,这里为何给出Java 8和Java 16版本说明?首先resizeStamp的bug在Java8出现,并在Java 12被修复,因此本文直接给出最新版Java 16作为bug修复前后对比即可。以下做个约定:统一以Java X形式作为版本称号,CHM:ConcurrentHashMap的简称,以此减少阅读障碍。在前面的文章中,关于Java 8 的CHM addCount方法里面分支2:resizeStamp和sc==rs+1、sc==rs+MAX_RESIZERS的讨论中,已经指出其bug嫌疑:privatefinalvoidaddCount(longx,intcheck){// 分支1 省略...// 分支2if(check=0){NodeK,V[]tab,nt;intn,sc;while(s=(long)(sc=sizeCtl)(tab=table)!=null(n=tab.length)MAXIMUM_CAPACITY){intrs=resizeStamp(n);// 注意这里计算出的rs是正值if(sc0){// sc是负值,怎么会等于rs+1或者rs + MAX_RESIZERS这个正值呢? 有可能是个bugif((scRESIZE_STAMP_SHIFT)!=rs||sc==rs+1||sc==rs+MAX_RESIZERS||(nt=nextTable)==null||transferIndex=0)break;if(U.compareAndSetInt(this,SIZECTL,sc,sc+1))transfer(tab,nt);}elseif(U.compareAndSetInt(this,SIZECTL,sc,(rsRESIZE_STAMP_SHIFT)+2))transfer(tab,null);s=sumCount();}}官方bug描述其实这个bug在open jdk的官方bugs主页已经给出相关解释和修复过程,链接:官方bug描述页面:从Detail这一块描述得到信息如下:bug的描述:ConcurrentHashMap.addCount()设计逻辑中可能存在bug。(这里虽然提到addCount()方法,但本人更想强调的是扩容分支的resizeStamp的bug)级别是:bug当前状态:已经修复影响的版本:Java 11、Java12在哪个版本得到修复:Java 12使用操作系统平台:所有bug页面创建时间:2018-11-26解决bug的最后时间:2018-12-11bug所属库:Java的核心库——core-libs提交者的修复建议In the above code, condition of (sc == rs + 1 || sc == rs + MAX_RESIZERS ) would never be true , since the value of rs is positive and the value of sc is negative .译:条件 (sc == rs + 1 || sc == rs + MAX_RESIZERS )永远不可能true,因为rs的值为正数,而sc值为负数并建议修改为:The correct condition should be (sc RESIZE_STAMP_SHIFT) == rs + 1 || (sc RESIZE_STAMP_SHIFT) == rs + MAX_RESIZERS, which can be used to dedect if resizing process finished or resizing threads reaches maxmium limitation译:正常的条件应该是这样: (sc RESIZE_STAMP_SHIFT) == rs + 1 || (sc RESIZE_STAMP_SHIFT) == rs + MAX_RESIZERS,这两个条件表示扩容任务已结束或者参与扩容的线程总数达到最大值确实,这个bug非常明显,以分支2作为说明int rs = resizeStamp(n),以容量n=16作为说明,rs计算为下面的值0000 0000 0000 0000 1000 0000 0001 1011考察低16位,rs+1的结果显然是一个正数0000 0000 0000 0000 1000 0000 0001 1100rs+MAX_RESIZERS同理也是一个正数,接着判断条件if(sc0)成立才能进入rs+1等条件,也即此时sc是一个负数(其实是因为首个扩容线程会将sc设为(rs RESIZE_STAMP_SHIFT) + 2的一个基础负数),基于此,有提交者在这里发现的了bug:sc是负数,而rs+1是正数,因此sc==rs+1永远不会成立官方关于此bug的讨论过程JCP JSR-166 Expert Group (关于Java并发编程的规范提案的专家组)几个相关成员的对话过程即可知道他们对问题的思考和处理方式。在Activity这个栏目就是用于提交者已经相关专家bug讨论过程,“All”是显示所有他们的活动记录,一般无需关注,“Comments”显示他们的对话过程,bug的讨论过程就在这里,因此需要重点关注,具体如下:以下是来自“Comments”区域的内容:(最开始由Webbug Group 这个小组提交了该issue - 2018-11-26 00:53)Stuart Marks 说:Stuart Marks added a comment - 2018-11-28 09:10Martin, can you take a look at this?Martin,来,帮我看看这个bug?Martin的回答,主要意思是:bug提交者在查一个确实是由addCount产生错误计数,但Martin说他们也没有可以使用的压测案例,并建议使用者用多线程做压测来让addCount的这个bug复现,但这个bug不好复现。Resizing the internal bucket array is hairy race-prone code, and hard to stress test because resizes are relatively rare.The reporter probably investigated an actual occurrence of incorrect count (we could ask!), but we don’t have a stress test reproduction that could be used.One should be able to construct a stress test using multiple threads to trigger concurrent attempts to addCount, but it won’t be easy.David Holmes 对Martin说:What is your analysis just based on the code and the report? It certainly appears incorrect to me.你的分析只是基于代码以及提交的报告?这个bug在我看来显然是不正确的。Martin回答David Holmes :Martin说自己也看了看源码但研究时间不够长,自己还没能搞懂其设计,然后说Doug应该记得这个设计!I stared at the code for a while, but not long enough to understand it. Doug will remember!Doug Lea added a comment - 2018-11-28 15:53:Doug Lea看到这个bug,做了基本的分析:这个bug会影响到CHM性能也即有些线程不能参与到扩容任务中,并指出这个bug只是影响性能而不是一个引起map发生错误的bug,指出这个bug需要修复。Yes. Some of this check now includes dead code, because of a change of representation at one point that wasn’t adjusted for. With the possible effect of some threads not helping resize (a performance, not map correctness bug) This should be fixed (and is committed in jdr166 repo):然后他贴出修复前后的源码diff---ConcurrentHashMap.java.~1.314.~2018-10-0513:42:39.860409607-0400+++ConcurrentHashMap.java2018-11-2818:48:55.998082379-0500@@-2307,9+2307,9@@(n=tab.length)MAXIMUM_CAPACITY){intrs=resizeStamp(n);if(sc0){-if((scRESIZE_STAMP_SHIFT

相关新闻

【Bug已解决】[Bug]: kv_cache_offloadig crashes on 0.21.0 - KeyError in self._block_id_to_pending_jobs[bid

【Bug已解决】[Bug]: kv_cache_offloadig crashes on 0.21.0 - KeyError in self._block_id_to_pending_jobs[bid

【Bug已解决】[Bug]: kv_cache_offloadig crashes on 0.21.0 - KeyError in self._block_id_to_pending_jobs[bid] 解决方案 一、现象长什么样 vLLM 0.21.0 开了 KV 缓存卸载(把冷 block 从显存搬到 CPU 内存/磁盘,腾显存给更热的请求&#x…

2026/7/28 11:17:23 阅读更多 →
级联H桥SVG无功补偿系统设计与电网不平衡解决方案

级联H桥SVG无功补偿系统设计与电网不平衡解决方案

1. 项目概述 在电力系统中,无功补偿是维持电网电压稳定、提高功率因数的关键技术手段。随着新能源大规模并网和电力电子设备普及,电网不平衡问题日益突出,传统无功补偿装置已难以满足现代电网需求。本项目聚焦于不平衡电网条件下的SVG&#x…

2026/7/28 11:17:23 阅读更多 →
ansible使用之——国产设备适配

ansible使用之——国产设备适配

ansible国产设备适配前言适配过程验证效果前言 ansible是美国redhat公司研发的一款开源的自动化运维工具,可以非常高效且可靠的实现对被控制端(服务器、网络设备等被控制节点)进行运维工作。然而,也同样由于此,其对国产…

2026/7/28 11:17:23 阅读更多 →

最新新闻

Hyperion财务智能系统发展历程与国产化替代解析

Hyperion财务智能系统发展历程与国产化替代解析

1. Hyperion发展历程全景解析 在企业管理软件领域,Hyperion(海波龙)的名字始终与财务智能紧密相连。作为全球领先的合并报表与预算管理解决方案,它的发展轨迹堪称企业级软件演进史的经典案例。我从业财务系统实施15年来&#xff0…

2026/7/28 11:29:27 阅读更多 →
FastFlix:开源视频格式转换工具的技术解析与应用

FastFlix:开源视频格式转换工具的技术解析与应用

1. FastFlix:视频格式转换的现代解决方案 在数字内容爆炸式增长的今天,视频格式转换已成为每个内容创作者、普通用户甚至企业团队都无法回避的日常需求。从4K超高清素材的后期处理,到手机拍摄视频的社交平台适配,再到老旧影视资料…

2026/7/28 11:29:27 阅读更多 →
Java Lambda实战:集合排序、多线程与空指针处理

Java Lambda实战:集合排序、多线程与空指针处理

1. 为什么我们需要Java Lambda实战手册 第一次接触Lambda表达式时,我被它的简洁语法惊艳到了。记得当时重构了一个满是匿名内部类的老项目,代码行数直接减少了40%。但真正深入使用后才发现,Lambda远不止是语法糖那么简单——它改变了我们处理…

2026/7/28 11:29:27 阅读更多 →
FigmaCN完整指南:3分钟实现Figma界面全中文汉化的终极解决方案

FigmaCN完整指南:3分钟实现Figma界面全中文汉化的终极解决方案

FigmaCN完整指南:3分钟实现Figma界面全中文汉化的终极解决方案 【免费下载链接】figmaCN 中文 Figma 插件,设计师人工翻译校验 项目地址: https://gitcode.com/gh_mirrors/fi/figmaCN 你是否在使用全球顶尖设计工具Figma时,因为英文界…

2026/7/28 11:29:27 阅读更多 →
Claude Code 代理式编码系统:从核心原理到实战部署的完整指南

Claude Code 代理式编码系统:从核心原理到实战部署的完整指南

最近在技术社区和开发者圈子里,Claude Code 的讨论热度持续攀升。很多朋友在尝试安装或使用时,遇到了诸如“无法连接到 Anthropic 服务”或“Claude Code 到底是什么”的困惑。本文旨在为你系统性地拆解 Claude Code,从核心概念、工作原理、典…

2026/7/28 11:29:26 阅读更多 →
FLUX.1-dev-ControlNet-Union:一站式AI图像控制终极指南

FLUX.1-dev-ControlNet-Union:一站式AI图像控制终极指南

FLUX.1-dev-ControlNet-Union:一站式AI图像控制终极指南 【免费下载链接】FLUX.1-dev-Controlnet-Union 项目地址: https://ai.gitcode.com/hf_mirrors/InstantX/FLUX.1-dev-Controlnet-Union 你是否曾经在AI图像生成中感到困惑?明明输入了详细的…

2026/7/28 11:28:26 阅读更多 →

日新闻

告别臃肿!3步让你的暗影精灵笔记本重获新生

告别臃肿!3步让你的暗影精灵笔记本重获新生

告别臃肿!3步让你的暗影精灵笔记本重获新生 【免费下载链接】OmenSuperHub Control Omen laptop performance, fan speeds, and keyboard lighting, and unlock power limits. 项目地址: https://gitcode.com/gh_mirrors/om/OmenSuperHub 你是否也曾为官方Om…

2026/7/28 0:00:43 阅读更多 →
RAG必踩坑!财报法规检索不准?这款开源工具让答案浮出水面,准确率飙升98.7%!

RAG必踩坑!财报法规检索不准?这款开源工具让答案浮出水面,准确率飙升98.7%!

做 RAG 的人应该都踩过这个致命的坑:把几百页的财报、法规、技术手册扔给向量库,问一个具体问题,搜出来的全是沾边但没用的内容 —— 关键信息要么被硬切块拆碎了,要么藏在几十条结果的最下面。语义相似≠真正相关,这个…

2026/7/28 0:00:43 阅读更多 →
抖音视频文案提取工具全指南:免费2026版、手机App、在线工具一网打尽

抖音视频文案提取工具全指南:免费2026版、手机App、在线工具一网打尽

2026年做短视频运营,从抖音上扒文案早就不是偷偷抄笔记的事了。我刚开始做内容的时候,每天刷半小时抖音,手动把爆款视频的口播敲进备忘录,一条2分钟的视频得花十来分钟,碰到语速快的还要反复回听。后来试了一圈工具&am…

2026/7/28 0:00:43 阅读更多 →

周新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档,可以直接使用!系统支持图片、视频、摄像头等多种方式检测裂缝,功能强大实用。 1数据集6000张 8各类别

2026/7/27 4:33:59 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像! pubg绝地求生目标检测数据集 1分类:e_body,14905个标签,txt格式 共计14244张图,99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/7/28 8:29:16 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别: allies enemy tag图片总量:7247张训练集:5139张验证集:1425张测试集:683张标注状态:全部已标注,即拿即用数据格式:支持YOLO格式及其他格式&#…

2026/7/28 5:03:42 阅读更多 →

月新闻