Web Worker 通过 SharedArrayBuffer 实现共享内存,需配合 Atomics 进行原子操作;普通 ArrayBuffer 仅复制传递,无法共享;必须在跨域隔离环境下使用。

Web Worker 通过 ArrayBuffer 实现共享内存,核心是使用 SharedArrayBuffer(而非普通 ArrayBuffer),配合 Atomics 进行线程安全的读写操作。普通 ArrayBuffer 是**复制传递**,无法共享;只有 SharedArrayBuffer 才真正让主线程与 Worker 共享同一块内存地址。
1. 创建 SharedArrayBuffer 并传给 Worker
主线程中创建 SharedArrayBuffer,并通过 postMessage 传递给 Worker(注意:需显式传入,不能放在对象属性里):
// 主线程
const sab = new SharedArrayBuffer(1024); // 1KB 共享内存
const int32View = new Int32Array(sab);
// 初始化一个值(例如位置 0 设为 42)
Atomics.store(int32View, 0, 42);
// 传给 Worker(必须在 message 的 transfer list 中)
worker.postMessage({ type: 'init', buffer: sab }, [sab]);
⚠️ 注意:[sab] 是 transfer list,表示把这块内存的所有权移交给 Worker —— 主线程此后不能再访问该 sab(除非再传回来),这是共享的前提。
2. Worker 端接收并建立视图
Worker 中监听消息,拿到 sab 后创建类型化数组视图(如 Int32Array),即可读写同一内存:
立即学习“Java免费学习笔记(深入)”;
// worker.js
let int32View;
self.onmessage = function(e) {
if (e.data.type === 'init') {
const sab = e.data.buffer;
int32View = new Int32Array(sab);
// 安全读取(带原子操作)
const value = Atomics.load(int32View, 0);
console.log('Worker received:', value); // 42
// 安全写入
Atomics.store(int32View, 0, 100);
}
};
3. 主线程与 Worker 协同读写需用 Atomics
直接读写 SharedArrayBuffer 视图可能引发竞态条件。必须用 Atomics 方法保证原子性:
-
Atomics.load(view, index)—— 安全读取 -
Atomics.store(view, index, value)—— 安全写入 -
Atomics.add(view, index, delta)—— 原子加法(适合计数器) -
Atomics.wait(view, index, expected, timeout)+Atomics.notify()—— 实现线程等待/唤醒
例如实现一个简单的计数器同步:
// Worker 中自增并通知 Atomics.add(int32View, 0, 1); Atomics.notify(int32View, 0, 1); // 唤醒最多 1 个在 wait 的线程 // 主线程中等待变更 Atomics.wait(int32View, 0, 42); // 阻塞直到位置 0 不再等于 42
4. 安全与兼容性注意事项
SharedArrayBuffer 有严格启用条件:
- 仅在支持 现代浏览器(Chrome 68+、Firefox 78+、Safari 15.4+)中可用
- 必须运行在 跨域隔离环境 下:页面需设置两个 HTTP 头:
Cross-Origin-Embedder-Policy: require-corpCross-Origin-Opener-Policy: same-origin - 本地 file:// 协议不支持,需用本地服务器(如 vite preview、http-server)
- 不能用于 DOM 操作或非数值型数据结构(如对象、字符串)—— 需自行按字节布局规划内存


















