TypedArray 本身不支持多线程原子操作,必须基于 SharedArrayBuffer 构建视图,并严格通过 Atomics 方法(如 load/store/add/compareExchange)进行读写;服务端需配置跨域隔离头,且 wait/notify 仅在 Worker 中可用。

TypedArray 本身不能直接用于多线程原子操作,必须搭配 SharedArrayBuffer 和 Atomics 才能安全读写共享内存。关键不是“用 TypedArray 做原子操作”,而是用 TypedArray 作为 SharedArrayBuffer 的视图,再通过 Atomics 方法访问——普通赋值(arr[i] = x)或读取(arr[i])仍是线程不安全的。
必须先创建 SharedArrayBuffer 并绑定视图
SharedArrayBuffer 是唯一支持跨线程共享的底层内存对象,TypedArray 必须基于它构造:
- 不能用
new ArrayBuffer(),它无法被多个线程同时访问; - 正确方式:
const sab = new SharedArrayBuffer(1024); const arr = new Int32Array(sab);; - 注意:虽然类型是
Int32Array,但后续所有读写必须通过Atomics.*函数,不能直接用arr[0] = 5。
所有访问必须走 Atomics 静态方法
Atomics 提供的每个函数都保证原子性与内存可见性,普通数组操作会被引擎优化、重排,导致竞态:
- 读值:
Atomics.load(arr, index)—— 等价于 volatile 读,确保看到最新写入; - 写值:
Atomics.store(arr, index, value)—— 强制刷新到共享内存,其他线程立即可见; - 加减:
Atomics.add(arr, index, delta)返回旧值,整个“读-改-写”不可中断; - 条件更新:
Atomics.compareExchange(arr, index, expected, replacement)是实现锁、计数器、无锁栈的核心。
服务端需启用跨域隔离策略
SharedArrayBuffer 和 Atomics 在现代浏览器中默认被禁用,除非页面满足跨域隔离要求:
- 响应头必须包含:
Cross-Origin-Opener-Policy: same-origin和Cross-Origin-Embedder-Policy: require-corp; - 缺少任一头部,
new SharedArrayBuffer()会抛出TypeError; - 本地开发时可用
http-server --cors --headers或使用localhost(部分浏览器豁免)临时调试。
Worker 中才能用 wait/notify 实现等待同步
Atomics.wait() 和 Atomics.notify() 仅在 Worker 线程中可用,主线程调用会直接报错:
- 典型模式:用
while (Atomics.load(arr, 0) === 0) { Atomics.wait(arr, 0, 0); }等待条件成立; - 唤醒方调用
Atomics.store(arr, 0, 1); Atomics.notify(arr, 0, 1);; - 务必套在 while 循环里,防止虚假唤醒(spurious wakeup)导致逻辑跳过。

















