SharedArrayBuffer 是共享内存区域,Atomics 提供原子操作保障线程安全;前者无同步机制,后者通过硬件级指令确保读写不可中断、立即可见,并需跨域隔离等限制。

SharedArrayBuffer 和 Atomics 是什么关系
SharedArrayBuffer 本身只是提供一块多个线程(如主线程和 Worker)可同时读写的内存区域,它不带任何同步机制。真正负责“保证操作安全”的是 Atomics 对象——它是一组静态方法,专为在 SharedArrayBuffer 上执行原子操作而设计。没有 Atomics,直接对 SharedArrayBuffer 的 Int32Array 等视图读写会导致竞态,结果不可预测。
Atomics 方法如何防止竞态
Atomics 的每个方法都确保:操作是「不可中断的」且「对所有线程立即可见」。例如 Atomics.add() 会原子性地读取、加值、写回,并返回旧值;期间其他线程无法插入读写。这依赖底层硬件支持的 CAS(Compare-And-Swap)或 LL/SC(Load-Linked/Store-Conditional)指令。
-
Atomics.load()和Atomics.store()保证单次读/写不被撕裂(tearing),且有内存顺序语义 -
Atomics.wait()+Atomics.notify()构成轻量级线程阻塞/唤醒机制,避免忙等待 - 所有
Atomics方法第一个参数必须是基于SharedArrayBuffer的TypedArray(如Int32Array),第二个是索引,不能越界
常见误用和关键限制
即使用了 Atomics,仍可能出错:
- 忘记启用跨域隔离:现代浏览器要求页面开启
crossorigin属性 +COOP/COEP头才能创建SharedArrayBuffer,否则构造失败并抛出TypeError: SharedArrayBuffer is not defined - 混用普通数组访问和
Atomics:比如用arr[0] = 1而非Atomics.store(arr, 0, 1),会绕过原子性保障 -
Atomics.wait()只对Int32Array有效,传Float64Array会直接报TypeError - 没有配合
Atomics.notify()使用wait(),会导致线程永久挂起
const sab = new SharedArrayBuffer(4); const ia = new Int32Array(sab); Atomics.store(ia, 0, 1); // 安全写入 console.log(Atomics.load(ia, 0)); // 安全读取 → 1 Atomics.add(ia, 0, 5); // 原子加 → 返回旧值 1,现在 ia[0] === 6
为什么不能只靠锁或 setTimeout 模拟
JavaScript 没有真正的线程锁(mutex)原语,setTimeout 或 Promise 无法解决共享内存竞态——它们只控制执行时机,不控制内存访问顺序。而 Atomics 是唯一能保证「一次读-改-写操作整体不可分割」的机制。它的安全性不是靠 JS 引擎调度,而是由运行时与操作系统、CPU 协同实现的底层保证。一旦忽略这个层级,多线程协作就退化为概率性正确。
立即学习“Java免费学习笔记(深入)”;











