JavaScript Shared Memory: SharedArrayBuffer and Atomics
Learn ECMAScript shared memory, SharedArrayBuffer, atomic read-modify-write operations, waiting and notification, and the memory-model boundary between shared storage and synchronization.
Advanced
Output
Ready to run.
Quick check
What makes SharedArrayBuffer different from ArrayBuffer?
const buffer = new SharedArrayBuffer(8);
document.querySelector("#output").textContent = `bytes: ${buffer.byteLength}`;
Output
Ready to run.
Quick check
What can a TypedArray do with a SharedArrayBuffer?
const buffer = new SharedArrayBuffer(4);
const bytes = new Uint8Array(buffer);
bytes[0] = 42;
document.querySelector("#output").textContent = `shared byte: ${bytes[0]}`;
Output
Ready to run.
Quick check
What does Atomics.add return?
const buffer = new SharedArrayBuffer(4);
const values = new Int32Array(buffer);
values[0] = 10;
const previous = Atomics.add(values, 0, 5);
document.querySelector("#output").textContent = `previous=${previous}; current=${values[0]}`;
Output
Ready to run.
Quick check
Why use Atomics.exchange?
const values = new Int32Array(new SharedArrayBuffer(4));
values[0] = 7;
const previous = Atomics.exchange(values, 0, 12);
document.querySelector("#output").textContent = `previous=${previous}; current=${values[0]}`;
Output
Ready to run.
Quick check
What does compareExchange test?
const values = new Int32Array(new SharedArrayBuffer(4));
values[0] = 10;
const previous = Atomics.compareExchange(values, 0, 10, 99);
document.querySelector("#output").textContent = `previous=${previous}; current=${values[0]}`;
Output
Ready to run.
Quick check
What is Atomics.load for?
const values = new Int32Array(new SharedArrayBuffer(4));
Atomics.store(values, 0, 25);
const result = Atomics.load(values, 0);
document.querySelector("#output").textContent = `loaded=${result}`;
Output
Ready to run.
Quick check
What does an Atomics bitwise operation change?
const values = new Int32Array(new SharedArrayBuffer(4));
Atomics.store(values, 0, 0b1010);
const previous = Atomics.or(values, 0, 0b0101);
document.querySelector("#output").textContent = `previous=${previous}; current=${values[0]}`;
Output
Ready to run.
Quick check
What does Atomics.sub return?
const values = new Int32Array(new SharedArrayBuffer(4));
values[0] = 20;
const previous = Atomics.sub(values, 0, 3);
document.querySelector("#output").textContent = `previous=${previous}; current=${values[0]}`;
Output
Ready to run.
Quick check
What does Atomics.isLockFree report?
const supported = Atomics.isLockFree(4);
document.querySelector("#output").textContent = `4-byte atomic operations lock-free: ${supported}`;
Output
Ready to run.
Quick check
What can Atomics.wait do?
const values = new Int32Array(new SharedArrayBuffer(4));
values[0] = 1;
const result = Atomics.wait(values, 0, 0, 0);
document.querySelector("#output").textContent = `wait result: ${result}`;
Output
Ready to run.
Quick check
What does Atomics.notify do?
const values = new Int32Array(new SharedArrayBuffer(4));
const notified = Atomics.notify(values, 0, 1);
document.querySelector("#output").textContent = `agents notified: ${notified}`;
Output
Ready to run.
Quick check
Which views are intended for Atomics operations?
const values = new Int32Array(new SharedArrayBuffer(4));
Atomics.store(values, 0, 41);
const next = Atomics.add(values, 0, 1);
document.querySelector("#output").textContent = `before=${next}; after=${values[0]}`;
Output
Ready to run.
Quick check
What is growable SharedArrayBuffer?
const buffer = new SharedArrayBuffer(4, { maxByteLength: 8 });
const before = buffer.byteLength;
let after = "unsupported";
if (typeof buffer.grow === "function") { buffer.grow(8); after = buffer.byteLength; }
document.querySelector("#output").textContent = `before=${before}; after=${after}`;
Output
Ready to run.
Quick check
Can a SharedArrayBuffer become detached?
const buffer = new SharedArrayBuffer(4);
const bytes = new Uint8Array(buffer);
bytes[0] = 9;
document.querySelector("#output").textContent = `bytes=${buffer.byteLength}; value=${bytes[0]}`;
Output
Ready to run.
Quick check
Why use Atomics for a shared counter?
const counter = new Int32Array(new SharedArrayBuffer(4));
Atomics.store(counter, 0, 0);
for (let i = 0; i < 3; i += 1) Atomics.add(counter, 0, 1);
document.querySelector("#output").textContent = `counter=${Atomics.load(counter, 0)}`;
Output
Ready to run.
Quick check
Why is the return value of Atomics.sub useful?
const values = new Int32Array(new SharedArrayBuffer(4));
Atomics.store(values, 0, 100);
const oldValue = Atomics.sub(values, 0, 25);
document.querySelector("#output").textContent = `returned=${oldValue}; stored=${values[0]}`;
Output
Ready to run.
Quick check
What is the safest way for a lesson to use Atomics.pause when the runtime may not implement it?
const supported = typeof Atomics.pause === "function";
document.querySelector("#output").textContent = supported ? "Atomics.pause is available" : "Atomics.pause is not available in this runtime";
Output
Ready to run.
Quick check
What does Atomics.pause contribute to a spin-wait loop?
const values = new Int32Array(new SharedArrayBuffer(4));
Atomics.store(values, 0, 1);
let attempts = 0;
while (Atomics.load(values, 0) !== 0 && attempts < 2) {
attempts += 1;
if (typeof Atomics.pause === "function") Atomics.pause();
if (attempts === 2) Atomics.store(values, 0, 0);
}
document.querySelector("#output").textContent = `attempts=${attempts}; value=${Atomics.load(values, 0)}`;
Output
Ready to run.
Quick check
Which statement distinguishes Atomics.pause from Atomics.wait?
const values = new Int32Array(new SharedArrayBuffer(4));
Atomics.store(values, 0, 7);
if (typeof Atomics.pause === "function") Atomics.pause();
const stillThere = Atomics.load(values, 0);
document.querySelector("#output").textContent = `value=${stillThere}`;
Output
Ready to run.
Quick check
Which concept remains the responsibility of the surrounding synchronization design rather than Atomics.pause itself?
const values = new Int32Array(new SharedArrayBuffer(4));
Atomics.store(values, 0, 0);
const before = Atomics.load(values, 0);
if (typeof Atomics.pause === "function") Atomics.pause();
Atomics.store(values, 0, 1);
document.querySelector("#output").textContent = `before=${before}; after=${Atomics.load(values, 0)}`;
Thanks for your feedback.
Mark this learning resource complete to track your learning progress.