atomicmarkablereference用于原子更新引用和布尔标记,解决二者不同步导致的竞态问题;通过compareandset确保引用与标记同时变更,适用于逻辑删除等双态场景,并可借助标记缓解aba问题。

AtomicMarkableReference 是 Java 并发包(java.util.concurrent.atomic)中一个专门用于“带标记的引用”原子操作的类。它允许你**同时、原子地更新一个对象引用和一个布尔标记(mark)**,常用于实现带状态的无锁算法,比如标记某个节点是否已被逻辑删除(如在并发链表或跳表中),或表示资源是否处于“已关闭”“已取消”等双态语义。
核心用途:解决引用 + 布尔状态的原子性问题
普通 AtomicReference 只能原子更新引用;若额外用一个 AtomicBoolean 管理标记,两者更新不同步,会出现竞态——比如线程 A 刚设好引用,还没来得及改标记,线程 B 就读到了“新引用 + 旧标记”,导致逻辑错乱。而 AtomicMarkableReference 把引用和标记打包成一个不可分割的单元,所有读写都基于这个组合值,天然保证二者一致性。
基本用法:创建、读取与原子更新
构造时需指定初始引用和初始标记;获取当前值时返回 Pair<v boolean></v>(内部封装为 [reference, mark]);关键方法是 compareAndSet,它要求**旧引用 + 旧标记完全匹配**才更新为新引用 + 新标记:
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
-
初始化:
AtomicMarkableReference<string> ref = new AtomicMarkableReference("hello", false);</string> -
读取当前值:
String currRef = ref.getReference(); boolean currMark = ref.isMarked();或一次性获取:ref.get(new boolean[1])(mark 写入传入数组第 0 位) -
安全更新:
boolean success = ref.compareAndSet(oldRef, newRef, oldMark, newMark);—— 四参数必须全部匹配才成功
典型场景:实现“延迟回收”的逻辑删除节点
例如在并发栈或链表中,删除节点不能直接 unlink(可能正被其他线程遍历),而是先打上“已删除”标记,后续再真正回收。此时 AtomicMarkableReference 可作为节点的 next 字段:
- 节点字段定义:
AtomicMarkableReference<node> next = new AtomicMarkableReference(null, false);</node> - 删除时:
next.compareAndSet(targetNode, targetNode, false, true);—— 标记该 next 指向的节点为“逻辑已删” - 遍历时检查:
if (next.isMarked()) { /* 跳过此节点 */ },避免访问已删数据
注意:标记仅表示状态,不自动释放内存;真正的物理回收仍需配合 GC 或无锁内存管理策略(如 epoch-based reclamation)。
注意事项:ABA 问题依然存在,但标记本身可辅助规避
AtomicMarkableReference 本身不消除 ABA(即引用从 A→B→A,CAS 误认为未变),但它把标记纳入比较维度,相当于将状态空间从“引用值”扩展为“引用+标记”二元组。只要业务逻辑中每次状态变更都翻转标记(如删除/恢复交替),就能有效区分真假 ABA。例如:首次删除设 mark=true,恢复时设 mark=false,再次删除再设 true——两次 true 对应不同逻辑时刻,CAS 不会混淆。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










