Signatur
Beschreibung
Mit new SharedArrayBuffer(length) legst du einen zusammenhängenden Speicherbereich von length Bytes an, der mit Nullen gefüllt ist. Anders als beim ArrayBuffer wird der Speicher bei der Übergabe per postMessage() an einen Worker nicht kopiert und nicht übertragen. Beide Seiten greifen auf denselben physischen Speicher zu.
Direkt lesen oder schreiben kannst du den Puffer nicht. Dafür brauchst du eine Sicht darauf, also ein typisiertes Array wie Int32Array oder eine DataView. Wenn mehrere Threads gleichzeitig zugreifen, solltest du Atomics verwenden (z. B. Atomics.add(), Atomics.wait(), Atomics.notify()). Nur so bleiben Lese- und Schreibvorgänge atomar und in der richtigen Reihenfolge.
Seit ES2024 kannst du mit der Option maxByteLength einen wachstumsfähigen Puffer anlegen. Er lässt sich mit grow() vergrößern, aber nie verkleinern. Typische Einsatzfälle sind WebAssembly-Threads, rechenintensive Parallelverarbeitung (Bild-/Audioverarbeitung) und Ringpuffer zwischen dem Haupt-Thread und einem AudioWorklet.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $length Pflicht | number | Größe des Puffers in Bytes. Nicht ganzzahlige Werte werden abgeschnitten. Negative oder zu große Werte lösen einen RangeError aus. |
|
| $options | object | Optionales Objekt. Unterstützt wird maxByteLength (number): die maximale Größe, auf die der Puffer mit grow() wachsen darf. Der Wert muss ≥ length sein. |
Rückgabewert
SharedArrayBuffer-Objekt der angegebenen Größe, mit Nullen initialisiert. Mit maxByteLength ist es wachstumsfähig (growable === true).Beispiele
Puffer anlegen und über ein typisiertes Array nutzen
const sab = new SharedArrayBuffer(16); // 16 Bytes
const view = new Int32Array(sab); // 4 × 32-Bit-Integer
view[0] = 42;
console.log(sab.byteLength, view.length, view[0]);
Gemeinsamer Zähler zwischen Haupt-Thread und Worker
// main.js
const sab = new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT);
const counter = new Int32Array(sab);
const worker = new Worker('worker.js');
worker.postMessage(sab); // kein Kopieren – gleicher Speicher
worker.onmessage = () => {
console.log('Zähler:', Atomics.load(counter, 0));
};
// worker.js
self.onmessage = ({ data }) => {
const counter = new Int32Array(data);
for (let i = 0; i < 1000; i++) Atomics.add(counter, 0, 1);
self.postMessage('fertig');
};
Wachstumsfähiger Puffer (ES2024)
const sab = new SharedArrayBuffer(8, { maxByteLength: 64 });
console.log(sab.growable, sab.byteLength, sab.maxByteLength);
sab.grow(32);
console.log(sab.byteLength);
try {
sab.grow(16); // Verkleinern ist nicht erlaubt
} catch (e) {
console.log(e.name);
}
Verfügbarkeit prüfen (Cross-Origin-Isolation)
if (typeof SharedArrayBuffer === 'undefined' || !globalThis.crossOriginIsolated) {
console.warn('SharedArrayBuffer nicht verfügbar – COOP/COEP-Header fehlen?');
} else {
const sab = new SharedArrayBuffer(1024);
console.log('OK:', sab.byteLength);
}
// Wichtig · Fallstricke
- Sicherheit / Cross-Origin-Isolation: Wegen Spectre ist
SharedArrayBufferin Browsern nur in cross-origin-isolierten Kontexten verfügbar. Dafür muss die Seite die HeaderCross-Origin-Opener-Policy: same-originundCross-Origin-Embedder-Policy: require-corp(odercredentialless) senden. Ob das greift, prüfst du mitcrossOriginIsolated. Außerdem ist ein sicherer Kontext (HTTPS) nötig. - Den Konstruktor musst du mit
newaufrufen.SharedArrayBuffer(8)ohnenewwirft einenTypeError. - Race Conditions: Normale Zugriffe über typisierte Arrays sind nicht synchronisiert. Für gemeinsam genutzte Zähler, Flags und Sperren brauchst du
Atomics. Atomics.wait()ist im Haupt-Thread von Browsern nicht erlaubt. Verwende dortAtomics.waitAsync().- Einen
SharedArrayBufferkannst du nicht in die Transfer-Liste vonpostMessage()aufnehmen. Er wird automatisch geteilt. - Einige APIs lehnen geteilten Speicher ab, etwa
TextDecoder.decode()in manchen Browsern. Dann musst du vorher in einenArrayBufferkopieren. - In Node.js ist
SharedArrayBufferohne Einschränkungen verfügbar (z. B. mitworker_threads). Die OptionmaxByteLengthgibt es ab Chrome 111, Firefox 128, Safari 16.4 und Node.js 20.