39. SharedArrayBuffer and Atomics: real shared-memory concurrency
Unlike a regular ArrayBuffer (owned by one realm at a time), a
SharedArrayBuffer can be given to multiple workers simultaneously,
with all of them reading and writing the same underlying memory — this is
genuine shared-memory multithreading, the first time JS ever had it.
// main.js
const sab = new SharedArrayBuffer(4); // 4 bytes = one Int32
const view = new Int32Array(sab);
Atomics.store(view, 0, 0);
worker.postMessage(sab); // NOT copied, NOT transferred — genuinely SHARED
worker.onmessage = () => console.log("final value:", Atomics.load(view, 0));
worker.postMessage("start");
// worker.js — receives the SAME memory, both threads can race on it
let sharedView;
self.onmessage = (e) => {
if (e.data instanceof SharedArrayBuffer) { sharedView = new Int32Array(e.data); return; }
for (let i = 0; i < 1000; i++) Atomics.add(sharedView, 0, 1); // ATOMIC increment — no lost updates
self.postMessage("done");
};
Atomics provides the lock-free primitives (add, compareExchange,
load, store, wait, notify) required to touch shared memory safely —
without them, two threads doing sharedView[0]++ concurrently is a classic
data race (read-modify-write isn't atomic), silently dropping increments.
Atomics.wait/notify implement real blocking synchronization (a
condition-variable-like primitive) between worker threads — genuinely novel
capability in JS, previously impossible without shared memory.
The security catch: SharedArrayBuffer was disabled globally across all
major browsers in 2018 in response to Spectre (a shared-memory, high-
resolution timer is exactly the primitive needed for that class of
speculative-execution side-channel attack). It's back today only on
pages that opt into cross-origin isolation:
# Required response headers on the top-level document to re-enable SharedArrayBuffer:
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
Without both headers set, typeof SharedArrayBuffer === "undefined" in the
page — this trips up a lot of teams trying to ship WASM-threads-based tools
(FFmpeg.wasm, SQLite-in-a-worker with true concurrency) who forget the
cross-origin-isolation requirement is now mandatory.