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

Atomics.load()

Methode

Liest den Wert an einer bestimmten Position eines Integer-TypedArrays atomar aus. So erhält man in jedem Fall einen vollständig geschriebenen, aktuellen Wert.

seit JavaScript ES2017 Kategorie: method-property

Signatur

Atomics.load(typedArray, index)

Beschreibung

Atomics.load() ist eine statische Methode des Atomics-Namensraums. Sie liest den Wert an Position index eines Integer-TypedArrays atomar. Der Lesezugriff wird also nie durch einen gleichzeitigen Schreibzugriff eines anderen Threads unterbrochen. Außerdem ist die Operation sequenziell konsistent: Schreibvorgänge, die ein anderer Agent (z. B. ein Web Worker) vorher mit Atomics.store() oder einer anderen Atomics-Methode abgeschlossen hat, sind danach sichtbar.

Wirklich nötig ist die Methode nur, wenn der Speicher mit einem SharedArrayBuffer zwischen mehreren Threads geteilt wird. Ein normaler Indexzugriff wie arr[i] kann dort durch Compiler- oder CPU-Optimierungen umgeordnet oder zwischengespeichert werden. Dann sieht ein Thread veraltete Werte, zum Beispiel wenn er in einer Schleife ein Flag abfragt. Atomics.load() verhindert solche Umordnungen.

Typische Einsatzfälle sind Status-Flags, Zähler, Ringpuffer-Indizes und selbst gebaute Sperren (Mutexe) zwischen dem Haupt-Thread und Workern. Die Methode funktioniert auch mit einem normalen ArrayBuffer. Dort bringt sie aber keinen Vorteil gegenüber einem einfachen Indexzugriff.

Parameter

Name Typ Default Beschreibung
$typedArray Pflicht Int8Array|Uint8Array|Int16Array|Uint16Array|Int32Array|Uint32Array|BigInt64Array|BigUint64Array Das Integer-TypedArray, aus dem gelesen wird. Meist liegt ihm ein SharedArrayBuffer zugrunde. Float32Array, Float64Array und Uint8ClampedArray sind nicht erlaubt.
$index Pflicht number Die Position im typedArray, von der gelesen wird. Sie muss im Bereich 0 bis length - 1 liegen.

Rückgabewert

Typ
number|bigint
Beschreibung
Der Wert an der angegebenen Position. Bei BigInt64Array und BigUint64Array ist er vom Typ bigint, sonst vom Typ number.

Beispiele

Einfaches atomares Lesen und Schreiben

const sab = new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4);
const arr = new Int32Array(sab);

Atomics.store(arr, 0, 42);
Atomics.add(arr, 0, 8);

console.log(Atomics.load(arr, 0));
50

Fortschritt eines Workers im Haupt-Thread abfragen

// main.js
const sab = new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT);
const progress = new Int32Array(sab);
const worker = new Worker('worker.js');
worker.postMessage(sab);

const timer = setInterval(() => {
  const done = Atomics.load(progress, 0);
  console.log(`Fortschritt: ${done} %`);
  if (done >= 100) clearInterval(timer);
}, 200);

// worker.js
// self.onmessage = ({ data }) => {
//   const progress = new Int32Array(data);
//   for (let i = 1; i <= 100; i++) {
//     // ... Arbeit erledigen ...
//     Atomics.store(progress, 0, i);
//   }
// };
Fortschritt: 12 % Fortschritt: 47 % ... Fortschritt: 100 %

Mit BigInt64Array arbeiten

const sab = new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * 2);
const counters = new BigInt64Array(sab);

Atomics.store(counters, 1, 9007199254740993n);
const value = Atomics.load(counters, 1);

console.log(value, typeof value);
9007199254740993n bigint

Fehlerfälle: falscher Array-Typ und ungültiger Index

const floats = new Float64Array(new SharedArrayBuffer(16));
try {
  Atomics.load(floats, 0);
} catch (e) {
  console.log(e.name); // TypeError
}

const ints = new Int32Array(new SharedArrayBuffer(8));
try {
  Atomics.load(ints, 5);
} catch (e) {
  console.log(e.name); // RangeError
}
TypeError RangeError

// Wichtig · Fallstricke

  • TypeError: Wird geworfen, wenn typedArray kein erlaubtes Integer-TypedArray ist (z. B. Float64Array oder Uint8ClampedArray).
  • RangeError: Wird geworfen, wenn index außerhalb der Array-Grenzen liegt. Anders als beim normalen Indexzugriff erhält man hier also kein undefined.
  • Voraussetzung SharedArrayBuffer: Seit Spectre ist SharedArrayBuffer in Browsern nur in cross-origin-isolierten Kontexten verfügbar. Dafür muss der Server die HTTP-Header Cross-Origin-Opener-Policy: same-origin und Cross-Origin-Embedder-Policy: require-corp senden. Ob die Seite isoliert ist, zeigt self.crossOriginIsolated.
  • Kein Warte-Mechanismus: Wer in einer Schleife ständig Atomics.load() aufruft (Busy-Waiting), verschwendet CPU-Zeit. Besser ist es, im Worker mit Atomics.wait() zu warten und mit Atomics.notify() aufzuwecken. Im Haupt-Thread ist Atomics.wait() nicht erlaubt, dort gibt es Atomics.waitAsync().
  • Kompatibilität: Wird von allen modernen Browsern und von Node.js (ab 8.10) unterstützt.