Signatur
Beschreibung
Atomics.and() ist eine statische Methode des Atomics-Namensraums. Sie liest den Wert an typedArray[index], berechnet alterWert & value, schreibt das Ergebnis an dieselbe Stelle und liefert den alten Wert zurück. Diese Lese-Rechne-Schreibe-Folge läuft atomar ab: Kein anderer Worker kann zwischen Lesen und Schreiben auf die Speicherzelle zugreifen.
Typischer Einsatzzweck ist das Löschen einzelner Bits in einem gemeinsam genutzten Status- oder Flag-Wort, etwa wenn mehrere Web Worker über einen SharedArrayBuffer Zustände (z. B. „bereit“, „beschäftigt“, „Fehler“) koordinieren. Mit einer Maske wie ~FLAG wird genau ein Bit auf 0 gesetzt, ohne die übrigen zu verändern – ein normales arr[i] &= ~FLAG wäre dagegen nicht threadsicher.
Die Methode funktioniert mit allen Integer-Typed-Arrays (Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, BigUint64Array). Sie kann auch auf Arrays über einem gewöhnlichen ArrayBuffer angewendet werden, sinnvoll ist sie aber vor allem mit SharedArrayBuffer.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $typedArray Pflicht | Int8Array|Uint8Array|Int16Array|Uint16Array|Int32Array|Uint32Array|BigInt64Array|BigUint64Array | Ein Integer-Typed-Array, idealerweise über einem SharedArrayBuffer. |
|
| $index Pflicht | number | Position im Array, an der die UND-Verknüpfung erfolgt. | |
| $value Pflicht | number|bigint | Die Bitmaske, mit der verknüpft wird. Bei BigInt64Array/BigUint64Array muss es ein bigint sein. |
Rückgabewert
typedArray[index] stand. Der neue Wert steht danach im Array.Beispiele
Grundprinzip: alter Wert wird zurückgegeben
const sab = new SharedArrayBuffer(Uint8Array.BYTES_PER_ELEMENT * 4);
const arr = new Uint8Array(sab);
arr[0] = 0b0111; // 7
const alt = Atomics.and(arr, 0, 0b0101); // 5
console.log(alt); // alter Wert
console.log(Atomics.load(arr, 0)); // 7 & 5 = 5
Status-Flag in einem gemeinsamen Speicher löschen
const FLAG_BEREIT = 1 << 0;
const FLAG_BESCHÄFTIGT = 1 << 1;
const FLAG_FEHLER = 1 << 2;
const status = new Int32Array(new SharedArrayBuffer(4));
Atomics.or(status, 0, FLAG_BEREIT | FLAG_BESCHÄFTIGT);
// Worker ist fertig: nur das Beschäftigt-Bit atomar entfernen
const vorher = Atomics.and(status, 0, ~FLAG_BESCHÄFTIGT);
console.log('war beschäftigt:', (vorher & FLAG_BESCHÄFTIGT) !== 0);
console.log('jetzt:', Atomics.load(status, 0).toString(2));
Mit BigInt64Array (64-Bit-Masken)
const big = new BigInt64Array(new SharedArrayBuffer(8));
big[0] = 0xFFFF_FFFF_FFn;
const alt = Atomics.and(big, 0, 0x0F0F_0F0F_0Fn);
console.log(alt.toString(16));
console.log(big[0].toString(16));
Worker räumt sein Bit auf und benachrichtigt Wartende
// main.js
const sab = new SharedArrayBuffer(4);
const aktiv = new Int32Array(sab);
aktiv[0] = 0b1111; // vier Worker aktiv
for (let id = 0; id < 4; id++) {
const w = new Worker('worker.js');
w.postMessage({ sab, id });
}
// worker.js
self.onmessage = ({ data: { sab, id } }) => {
const aktiv = new Int32Array(sab);
// ... Arbeit erledigen ...
const vorher = Atomics.and(aktiv, 0, ~(1 << id));
if ((vorher & ~(1 << id)) === 0) {
// letzter Worker: Wartende wecken
Atomics.notify(aktiv, 0);
}
};
// Wichtig · Fallstricke
- Rückgabewert ist der alte Wert, nicht das Ergebnis. Das neue Ergebnis erhält man mit
Atomics.load()oder durchalt & value. - Wirft einen
TypeError, wenntypedArraykein Integer-Typed-Array ist (z. B.Float64ArrayoderUint8ClampedArray) oder wenn bei BigInt-Arrays einnumberstattbigintübergeben wird (und umgekehrt). - Wirft einen
RangeError, wennindexaußerhalb der Array-Grenzen liegt. valuewird in den Elementtyp umgewandelt: BeiUint8Arrayergibt~FLAG(negativ) zwar korrekt die gekürzte Maske, bei der Auswertung des Rückgabewerts aber auf Vorzeichen achten.SharedArrayBufferist im Browser nur in cross-origin-isolierten Kontexten verfügbar (HeaderCross-Origin-Opener-Policy: same-originundCross-Origin-Embedder-Policy: require-corp), eine Folge der Spectre-Abwehr. Prüfen mitself.crossOriginIsolated.- Unterstützt in allen modernen Browsern und Node.js 8.10+; BigInt-Arrays ab ES2020.