Signatur
Beschreibung
Atomics.xor() liest den Wert an typedArray[index], verknüpft ihn bitweise per XOR (^) mit value, schreibt das Ergebnis zurück und liefert den ursprünglichen Wert. Die drei Schritte laufen als eine unteilbare Operation ab: Kein anderer Thread (z. B. ein Web Worker) kann zwischen Lesen und Schreiben auf die Speicherstelle zugreifen.
Typische Einsatzfälle sind das Umschalten (Toggeln) von Bit-Flags in einem SharedArrayBuffer, den mehrere Worker gemeinsam nutzen, etwa Status- oder Paritätsbits. Ein normales arr[i] ^= mask wäre hier eine Race Condition, weil Lesen und Schreiben getrennt stattfinden.
Die Methode funktioniert mit allen Integer-TypedArrays (Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, BigUint64Array), und zwar mit geteiltem wie mit nicht geteiltem Speicher. Bei den BigInt-Varianten muss value ein BigInt sein.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $typedArray Pflicht | Int8Array|Uint8Array|Int16Array|Uint16Array|Int32Array|Uint32Array|BigInt64Array|BigUint64Array | Integer-TypedArray, meist über einem SharedArrayBuffer. |
|
| $index Pflicht | number | Position im typedArray, an der das XOR ausgeführt wird. |
|
| $value Pflicht | number|bigint | Operand für das XOR. Wird in den Elementtyp des Arrays umgewandelt (bei BigInt-Arrays: BigInt). |
Rückgabewert
typedArray[index] vor dem XOR. Den neuen Wert erhält man mit alt ^ value oder Atomics.load().Beispiele
Grundlegende Verwendung
const sab = new SharedArrayBuffer(16);
const ta = new Uint8Array(sab);
ta[0] = 5; // 0b0101
const alt = Atomics.xor(ta, 0, 1); // 0b0101 ^ 0b0001
console.log(alt);
console.log(Atomics.load(ta, 0));
Status-Flag zwischen Worker und Hauptthread umschalten
// main.js
const FLAG_PAUSED = 0b0001;
const FLAG_DEBUG = 0b0100;
const sab = new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT);
const flags = new Int32Array(sab);
const worker = new Worker('worker.js');
worker.postMessage(flags);
// Pause-Flag atomar toggeln
const toggleFlag = (mask) => {
const vorher = Atomics.xor(flags, 0, mask);
const jetztGesetzt = ((vorher ^ mask) & mask) !== 0;
console.log(`Flag ${mask}: ${jetztGesetzt ? 'an' : 'aus'}`);
};
toggleFlag(FLAG_PAUSED);
toggleFlag(FLAG_DEBUG);
toggleFlag(FLAG_PAUSED);
Mit BigInt64Array
const big = new BigInt64Array(new SharedArrayBuffer(8));
big[0] = 0xFFn;
const alt = Atomics.xor(big, 0, 0x0Fn);
console.log(alt, big[0]);
// Wichtig · Fallstricke
- Rückgabewert ist der alte Wert, nicht das Ergebnis. Das ist ein häufiger Denkfehler.
- Wirft
TypeError, wenntypedArraykein Integer-TypedArray ist (z. B.Float64ArrayoderUint8ClampedArray), undRangeError, wennindexaußerhalb der Grenzen liegt. - Bei
BigInt64Array/BigUint64Arrayführt eine normale Zahl alsvaluezu einemTypeError. Umgekehrt gilt das Gleiche. - Werte außerhalb des Elementbereichs werden abgeschnitten (z. B. bei
Uint8Arraymodulo 256). SharedArrayBuffersteht im Browser nur in cross-origin-isolierten Kontexten zur Verfügung. Dafür braucht es die HeaderCross-Origin-Opener-Policy: same-originundCross-Origin-Embedder-Policy: require-corp(Grund: Schutz vor Spectre).Atomicsselbst wird von allen modernen Browsern und von Node.js unterstützt.Atomics.xor()weckt keine wartenden Threads. Dafür ist nach dem SchreibenAtomics.notify()nötig.