Workers normally share nothing: postMessage copies data, or transfers an ArrayBuffer so only one side owns it. A SharedArrayBuffer (SAB) is a buffer that several agents (the main thread and workers) see at the same time. Posting it sends a handle to the same memory, not a copy. It is the building block for multi-threaded code such as WebAssembly threads, and the right tool only when copying or transferring is too slow or you need real concurrent access.
Concurrent access is dangerous. counter[0]++ is a read, an add, and a write, so two threads can both read 5 and both write 6 (a data race, a lost update). Atomics fixes this for integer typed arrays over a buffer:
- Atomic read-modify-write:
Atomics.add,sub,and,or,xor,exchange,compareExchange. Each completes indivisibly. Atomic accesses are sequentially consistent. load/store: atomic reads and writes of one element.Atomics.wait(ta, i, expected, timeout?)blocks the agent whileta[i] === expected, returning"ok","not-equal", or"timed-out". It needs anInt32ArrayorBigInt64Arrayon a SAB, and throwsTypeErrorwhere the agent may not block, such as a browser's main thread.Atomics.waitAsync(ES2024) does the same without blocking: it returns{ async, value }, wherevalueis a Promise whenasyncistrue.Atomics.notify(ta, i, count?)wakes waiters and returns how many it woke.Atomics.pause()(stage 4, ES2027; Node 24+) is a CPU hint for spin loops.
Browser requirement. SharedArrayBuffer needs a secure context and a cross-origin isolated page: the document is served with Cross-Origin-Opener-Policy: same-origin and Cross-Origin-Embedder-Policy: require-corp (or credentialless). Without them the constructor is hidden and postMessage of a SAB throws. Check crossOriginIsolated. Node has no such restriction.