SharedArrayBuffer and Atomics
JavaScript is traditionally single-threaded. However, with Web Workers, you can run code in background threads. Historically, communicating between the main thread and workers involved postMessage, which copies data (slow for large datasets).
SharedArrayBuffer and Atomics allow different threads to read and write to the same chunk of memory instantly, without copying.
1. SharedArrayBuffer
A SharedArrayBuffer is similar to an ArrayBuffer, but it can be shared between agents (the main thread and web workers).
// Main Thread
const sharedBuffer = new SharedArrayBuffer(1024); // 1KB buffer
const sharedArray = new Int32Array(sharedBuffer);
// Send the buffer to a worker
worker.postMessage(sharedBuffer);
When the worker receives it, it doesn't get a copy; it gets access to the same memory.
2. The Problem: Race Conditions
When two threads modify the same memory location at the same time, you get race conditions.
Scenario:
- Thread A reads value
0. - Thread B reads value
0. - Thread A adds 1 and writes
1. - Thread B adds 1 and writes
1.
Result: 1 (Expected 2).
3. The Solution: Atomics
The Atomics object provides static methods to perform atomic operations. An atomic operation ensures that the read-modify-write process happens as a single, indivisible step. No other thread can interrupt it.
Basic Operations
const buffer = new SharedArrayBuffer(16);
const uint8 = new Uint8Array(buffer);
uint8[0] = 7;
// 1. Add (Atomic read-modify-write)
// Adds 2 to the value at index 0. Returns the OLD value.
Atomics.add(uint8, 0, 2);
console.log(Atomics.load(uint8, 0)); // 9
// 2. Store and Load
Atomics.store(uint8, 0, 10); // Safe write
console.log(Atomics.load(uint8, 0)); // Safe read
// 3. Compare Exchange
// If value at index 0 is 10, replace it with 20.
Atomics.compareExchange(uint8, 0, 10, 20);
4. Synchronization (Wait and Notify)
Atomics also provides a way to make threads wait for a signal, effectively implementing locks/mutexes.
Atomics.wait(typedArray, index, value): Verifies that the value atindexisvalue. If so, it puts the thread to sleep until it is notified or times out. (Cannot be used on the main thread).Atomics.notify(typedArray, index, count): Wakes up threads waiting on that index.
// Worker Thread
Atomics.wait(int32Array, 0, 0); // Wait here while index 0 equals 0
console.log("Awake!");
// Main Thread
Atomics.store(int32Array, 0, 1); // Change value
Atomics.notify(int32Array, 0, 1); // Wake up 1 worker
5. Security Requirements
Due to CPU vulnerabilities like Spectre, SharedArrayBuffer is disabled in browsers unless the page is "Cross-Origin Isolated". You must serve your page with these headers:
Cross-Origin-Opener-Policy: same-originCross-Origin-Embedder-Policy: require-corp
programming/javascript/vanilla/javascript programming/javascript/vanilla/typed-arrays