sharedarraybuffer 与 atomics 共同构成 web 平台跨线程共享内存与同步操作的核心机制,提供内存级原子读写、cas、wait/notify 等底层并发原语,需 cross-origin isolated 环境且不被 safari 支持。

SharedArrayBuffer 和 Atomics 是 JavaScript 中实现真正跨线程(如主线程与 Worker 之间)**共享内存 + 同步操作**的核心机制,它们共同构成 Web 平台上的低层并发原语。不同于 Promise 或 async/await 这类基于事件循环的“逻辑异步”,它们提供的是**内存级的同步能力**,能解决多线程读写竞争、等待通知、原子更新等关键问题。
SharedArrayBuffer:共享内存的载体
SharedArrayBuffer 是一块可以被多个线程(比如主线程和 Web Worker)同时访问的原始二进制内存区域。它不包含类型信息,必须配合 TypedArray(如 Int32Array、Float64Array)来读写数据。
关键点:
- 创建后需显式传递给 Worker(通过
postMessage(..., [sab])),否则 Worker 无法访问; - 不能直接序列化,必须用
transferable方式传递(避免拷贝,也防止原线程再访问); - 所有线程看到的是同一块物理内存,因此普通读写存在竞态——必须用 Atomics 保证安全。
Atomics:提供原子操作和线程协调原语
Atomics 是一个静态对象,提供一系列不可中断的底层操作,用于在 SharedArrayBuffer 上安全地读、写、修改、等待和唤醒线程。它不是“锁”,而是更轻量、更灵活的同步工具。
常用方法说明:
-
Atomics.load(ta, index):原子读取指定位置的值(避免读到中间状态); -
Atomics.store(ta, index, value):原子写入; -
Atomics.add(ta, index, value):原子加法并返回旧值(类似 CAS 前置操作); -
Atomics.compareExchange(ta, index, expected, replacement):核心 CAS 操作,是实现自定义锁、计数器、无锁结构的基础; -
Atomics.wait(ta, index, value, timeout):让当前线程休眠,直到该位置值 ≠ value(常用于“等待条件”); -
Atomics.notify(ta, index, count):唤醒最多 count 个正在 wait 该位置的线程(类似 condition variable signal)。
典型协作模式:生产者-消费者 + 条件等待
例如主线程向 Worker 发送任务,Worker 处理完后通知主线程结果就绪:
- 分配一个 SharedArrayBuffer,用 Int32Array 映射,如
const sab = new SharedArrayBuffer(4); const view = new Int32Array(sab);; - 约定
view[0]表示状态:0=空闲、1=处理中、2=完成; - Worker 执行任务前
Atomics.compareExchange(view, 0, 0, 1)尝试抢锁;成功则执行,完成后Atomics.store(view, 0, 2)并Atomics.notify(view, 0, 1); - 主线程用
Atomics.wait(view, 0, 2)阻塞等待(注意:只能在 Worker 线程或启用crossOriginIsolated的主线程中调用!),被唤醒后检查值并继续。
重要前提与限制
使用 SharedArrayBuffer 和 Atomics 有严格运行环境要求:
- 页面必须处于 cross-origin isolated 状态(即响应头含
Cross-Origin-Embedder-Policy: require-corp和Cross-Origin-Opener-Policy: same-origin); -
Atomics.wait()只能在非主线程(Worker)或明确启用allow-unsafe-eval等策略的主线程中调用(多数浏览器禁止主线程 wait,以防阻塞 UI); - 不支持 Safari(截至 2024 年仍无计划支持 Atomics.wait/notify);
- 没有高级抽象(如 Mutex、Semaphore),需手动组合 Atomics 构建,容易出错——建议封装复用。
它不是为日常业务逻辑设计的“异步同步化”方案,而是面向高性能计算、音视频处理、游戏引擎等需要细粒度线程协作的场景。用对了,效率极高;用错了,可能死锁或内存不一致。不复杂但容易忽略隔离策略和浏览器兼容性。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











