Start · Sprachen · JavaScript · Referenz · Atomics.notify()

Atomics.notify()

Methode

Weckt Agenten (z. B. Worker), die mit <code>Atomics.wait()</code> oder <code>Atomics.waitAsync()</code> an einer Speicherstelle eines geteilten Arrays warten.

seit JavaScript ES2017 (Baseline: alle modernen Browser, Node.js 8 Kategorie: method-property

Signatur

Atomics.notify(typedArray, index, count)

Beschreibung

Atomics.notify() ist das Gegenstück zu Atomics.wait() und Atomics.waitAsync(). Wartet ein Agent (ein Worker oder der Hauptthread per waitAsync) an einer bestimmten Position eines Int32Array oder BigInt64Array auf einem SharedArrayBuffer, kann ein anderer Agent ihn mit notify() wecken. Damit lassen sich eigene Synchronisationsmittel wie Mutexe, Semaphoren, Bedingungsvariablen oder Erzeuger-Verbraucher-Warteschlangen bauen.

Die Methode weckt bis zu count wartende Agenten in der Reihenfolge, in der sie mit dem Warten begonnen haben (FIFO). Wird count weggelassen, werden alle Wartenden an dieser Stelle geweckt. Zurückgegeben wird die Zahl der tatsächlich geweckten Agenten – 0, wenn gerade niemand wartet.

Wichtig: notify() verändert den Wert im Array nicht. Das übliche Muster ist daher: erst den Wert mit Atomics.store() oder einer anderen atomaren Operation ändern, dann Atomics.notify() aufrufen. Der wartende Agent prüft nach dem Aufwachen den Wert erneut, weil ein Aufwachen nicht garantiert, dass sich die Bedingung wirklich erfüllt hat.

Im Gegensatz zu Atomics.wait() blockiert notify() nie. Sie darf deshalb auch im Hauptthread des Browsers aufgerufen werden.

Parameter

Name Typ Default Beschreibung
$typedArray Pflicht Int32Array | BigInt64Array Ganzzahl-Array, an dessen Speicherstelle gewartet wird. Nur bei einem SharedArrayBuffer als Grundlage können tatsächlich Agenten geweckt werden.
$index Pflicht number Position im typedArray, an der die Agenten warten.
$count number Infinity Höchstzahl der Agenten, die geweckt werden. Fehlt der Wert oder ist er undefined, werden alle Wartenden geweckt. Negative Werte gelten als 0.

Rückgabewert

Typ
number
Beschreibung
Anzahl der tatsächlich geweckten Agenten. Liegt dem Array ein nicht geteilter ArrayBuffer zugrunde, ist das Ergebnis immer 0.

Beispiele

Worker warten lassen und aus dem Hauptthread wecken

// main.js
const sab = new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT);
const flag = new Int32Array(sab);

const worker = new Worker('worker.js');
worker.postMessage(sab);

setTimeout(() => {
  Atomics.store(flag, 0, 1);            // erst den Wert ändern …
  const woken = Atomics.notify(flag, 0); // … dann benachrichtigen
  console.log(`Geweckte Agenten: ${woken}`);
}, 1000);

// worker.js
self.onmessage = ({ data }) => {
  const flag = new Int32Array(data);
  // Blockiert, solange flag[0] === 0 ist
  const result = Atomics.wait(flag, 0, 0);
  console.log(`Worker aufgewacht: ${result}, Wert: ${Atomics.load(flag, 0)}`);
};
Geweckte Agenten: 1 Worker aufgewacht: ok, Wert: 1

Nur einen von mehreren Wartenden wecken

// main.js – vier Worker warten an derselben Stelle
const sab = new SharedArrayBuffer(4);
const ticket = new Int32Array(sab);

const workers = Array.from({ length: 4 }, () => {
  const w = new Worker('waiter.js');
  w.postMessage(sab);
  return w;
});

setTimeout(() => {
  Atomics.add(ticket, 0, 1);
  // Genau einen Worker wecken (Semaphore-ähnlich)
  console.log(Atomics.notify(ticket, 0, 1));
}, 500);

// waiter.js
self.onmessage = ({ data }) => {
  const ticket = new Int32Array(data);
  Atomics.wait(ticket, 0, 0);
  postMessage('bin dran');
};
1

Zusammenspiel mit Atomics.waitAsync() im Hauptthread

const sab = new SharedArrayBuffer(4);
const state = new Int32Array(sab);

// Nicht-blockierendes Warten (ES2024)
const { async, value } = Atomics.waitAsync(state, 0, 0, 5000);

if (async) {
  value.then((result) => console.log(`Ergebnis: ${result}`));
}

Atomics.store(state, 0, 42);
console.log(`Geweckt: ${Atomics.notify(state, 0)}`);
Geweckt: 1 Ergebnis: ok

Kein Wartender, nicht geteilter Speicher

const plain = new Int32Array(4); // normaler ArrayBuffer
console.log(Atomics.notify(plain, 0));

const shared = new Int32Array(new SharedArrayBuffer(16));
console.log(Atomics.notify(shared, 2, 10)); // niemand wartet
0 0

// Wichtig · Fallstricke

  • Reihenfolge beachten: Erst den geteilten Wert atomar ändern, dann notify() aufrufen. Andernfalls kann ein Agent zwischen Prüfung und Warten ein Signal verpassen (Lost Wake-up). Wartende sollten den Wert nach dem Aufwachen immer in einer Schleife erneut prüfen.
  • Nur Integer-Arrays: Andere Typen (z. B. Uint8Array, Float64Array, Uint32Array) lösen einen TypeError aus. Ein index außerhalb des Bereichs wirft einen RangeError.
  • SharedArrayBuffer-Voraussetzung: Im Browser steht SharedArrayBuffer nur in cross-origin isolated Kontexten zur Verfügung. Die Seite muss mit Cross-Origin-Opener-Policy: same-origin und Cross-Origin-Embedder-Policy: require-corp (oder credentialless) ausgeliefert werden – eine Folge der Spectre-Schutzmaßnahmen. Prüfen lässt sich das über self.crossOriginIsolated.
  • Umbenennung: In frühen Entwürfen hieß die Methode Atomics.wake(). Dieser Name wurde entfernt und sollte nicht mehr verwendet werden.
  • notify() blockiert nie und ist daher auch im Hauptthread erlaubt, Atomics.wait() dagegen meist nicht. Dort Atomics.waitAsync() verwenden.