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

Atomics.and()

Methode

Verknüpft den Wert an einer Position eines Integer-Typed-Arrays atomar per bitweisem UND mit <code>value</code>, schreibt das Ergebnis zurück und gibt den alten Wert zurück.

seit JavaScript ES2017 Kategorie: method-property

Signatur

Atomics.and(typedArray, index, value)

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

Typ
number|bigint
Beschreibung
Der Wert, der vor der Operation an 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
7 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));
war beschäftigt: true jetzt: 1

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));
ffffffffff f0f0f0f0f

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 durch alt & value.
  • Wirft einen TypeError, wenn typedArray kein Integer-Typed-Array ist (z. B. Float64Array oder Uint8ClampedArray) oder wenn bei BigInt-Arrays ein number statt bigint übergeben wird (und umgekehrt).
  • Wirft einen RangeError, wenn index außerhalb der Array-Grenzen liegt.
  • value wird in den Elementtyp umgewandelt: Bei Uint8Array ergibt ~FLAG (negativ) zwar korrekt die gekürzte Maske, bei der Auswertung des Rückgabewerts aber auf Vorzeichen achten.
  • SharedArrayBuffer ist im Browser nur in cross-origin-isolierten Kontexten verfügbar (Header Cross-Origin-Opener-Policy: same-origin und Cross-Origin-Embedder-Policy: require-corp), eine Folge der Spectre-Abwehr. Prüfen mit self.crossOriginIsolated.
  • Unterstützt in allen modernen Browsern und Node.js 8.10+; BigInt-Arrays ab ES2020.