Signatur
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
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));
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);
// }
// };
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);
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
}
// Wichtig · Fallstricke
- TypeError: Wird geworfen, wenn
typedArraykein erlaubtes Integer-TypedArray ist (z. B.Float64ArrayoderUint8ClampedArray). - RangeError: Wird geworfen, wenn
indexaußerhalb der Array-Grenzen liegt. Anders als beim normalen Indexzugriff erhält man hier also keinundefined. - Voraussetzung SharedArrayBuffer: Seit Spectre ist
SharedArrayBufferin Browsern nur in cross-origin-isolierten Kontexten verfügbar. Dafür muss der Server die HTTP-HeaderCross-Origin-Opener-Policy: same-originundCross-Origin-Embedder-Policy: require-corpsenden. Ob die Seite isoliert ist, zeigtself.crossOriginIsolated. - Kein Warte-Mechanismus: Wer in einer Schleife ständig
Atomics.load()aufruft (Busy-Waiting), verschwendet CPU-Zeit. Besser ist es, im Worker mitAtomics.wait()zu warten und mitAtomics.notify()aufzuwecken. Im Haupt-Thread istAtomics.wait()nicht erlaubt, dort gibt esAtomics.waitAsync(). - Kompatibilität: Wird von allen modernen Browsern und von Node.js (ab 8.10) unterstützt.