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

Atomics.isLockFree()

Methode

Prüft, ob atomare Operationen auf Elementen mit der angegebenen Byte-Größe ohne Sperren (lock-free, direkt per Hardware-Instruktion) ausgeführt werden.

seit JavaScript ES2017 (Baseline: alle modernen Browser, Node.js 8 Kategorie: method-property

Signatur

Atomics.isLockFree(size)

Beschreibung

Atomics.isLockFree() ist eine statische Methode des Atomics-Namensraums. Sie gibt an, ob die Atomics-Methoden (z. B. Atomics.add(), Atomics.compareExchange()) für Array-Elemente der Größe size Bytes atomare Hardware-Instruktionen verwenden oder intern auf eine Sperre (Lock) zurückgreifen müssen.

Sinnvolle Werte für size entsprechen dem BYTES_PER_ELEMENT typisierter Arrays: 1 (Int8Array/Uint8Array), 2 (Int16Array/Uint16Array), 4 (Int32Array/Uint32Array) und 8 (BigInt64Array/BigUint64Array). Alle anderen Werte liefern false.

Die Methode richtet sich an Entwickler hochperformanter, nebenläufiger Algorithmen (z. B. eigene Mutexe, Lock-free-Queues, Ringpuffer zwischen Workern oder WebAssembly-Threads). Ist eine Größe lock-free, sind Operationen darauf in der Regel deutlich schneller und unterliegen keiner Blockade durch interne Sperren. Laut Spezifikation liefert Atomics.isLockFree(4) immer true – Int32Array ist daher die portabelste Wahl für geteilten Zustand.

Parameter

Name Typ Default Beschreibung
$size Pflicht number Größe eines Elements in Bytes. Wird per ToIntegerOrInfinity in eine Ganzzahl umgewandelt; relevant sind 1, 2, 4 und 8.

Rückgabewert

Typ
boolean
Beschreibung
true, wenn atomare Operationen auf Elementen dieser Größe ohne Sperre ausgeführt werden, sonst false. Für 4 immer true, für nicht unterstützte Größen (z. B. 3, 16) immer false.

Beispiele

Unterstützte Elementgrößen abfragen

const sizes = [1, 2, 3, 4, 8, 16];

for (const size of sizes) {
  console.log(`${size} Byte(s):`, Atomics.isLockFree(size));
}
1 Byte(s): true 2 Byte(s): true 3 Byte(s): false 4 Byte(s): true 8 Byte(s): true 16 Byte(s): false (Werte für 1, 2 und 8 sind plattformabhängig; typische Ausgabe auf x64 mit V8)

Direkt mit BYTES_PER_ELEMENT eines typisierten Arrays prüfen

const arrayTypes = [Int8Array, Int16Array, Int32Array, BigInt64Array];

const report = arrayTypes.map((Type) => ({
  typ: Type.name,
  bytes: Type.BYTES_PER_ELEMENT,
  lockFree: Atomics.isLockFree(Type.BYTES_PER_ELEMENT),
}));

console.table(report);
┌─────────┬─────────────────┬───────┬──────────┐ │ (index) │ typ │ bytes │ lockFree │ ├─────────┼─────────────────┼───────┼──────────┤ │ 0 │ 'Int8Array' │ 1 │ true │ │ 1 │ 'Int16Array' │ 2 │ true │ │ 2 │ 'Int32Array' │ 4 │ true │ │ 3 │ 'BigInt64Array' │ 8 │ true │ └─────────┴─────────────────┴───────┴──────────┘

Zählertyp für geteilten Speicher zwischen Workern wählen

// Bevorzugt 64-Bit-Zähler, falls lock-free; sonst sicherer 32-Bit-Fallback
const createSharedCounter = () => {
  if (Atomics.isLockFree(8) && typeof SharedArrayBuffer !== 'undefined') {
    const counter = new BigInt64Array(new SharedArrayBuffer(8));
    return { counter, inc: () => Atomics.add(counter, 0, 1n) };
  }
  // 4 Byte sind laut Spezifikation immer lock-free
  const counter = new Int32Array(new SharedArrayBuffer(4));
  return { counter, inc: () => Atomics.add(counter, 0, 1) };
};

const { counter, inc } = createSharedCounter();
inc();
inc();
console.log(Atomics.load(counter, 0));
2n (bzw. 2 beim 32-Bit-Fallback)

// Wichtig · Fallstricke

  • Nur 4 ist garantiert: Die Spezifikation schreibt vor, dass Atomics.isLockFree(4) immer true liefert. Die Ergebnisse für 1, 2 und 8 sind implementierungs- und hardwareabhängig – verlasse dich nicht auf feste Werte, sondern frage zur Laufzeit ab.
  • Korrektheit ist unabhängig vom Ergebnis: Auch bei false arbeiten alle Atomics-Methoden korrekt atomar – nur eben über eine interne Sperre und damit meist langsamer. Die Methode ist ein Performance-, kein Sicherheitsmerkmal.
  • Kein Argument-Fehler: Ungültige Werte (z. B. 3, 'abc', NaN) werfen keinen Fehler, sondern liefern false. Strings wie '4' werden in Zahlen umgewandelt.
  • SharedArrayBuffer-Voraussetzungen: Atomics.isLockFree() selbst funktioniert überall, praktisch nutzbar ist geteilter Speicher im Browser aber nur in cross-origin-isolierten Kontexten (Header Cross-Origin-Opener-Policy: same-origin und Cross-Origin-Embedder-Policy: require-corp). Prüfe dies über self.crossOriginIsolated.
  • Unterstützt in allen modernen Browsern sowie Node.js; in sehr alten Browsern (vor 2017/2018) fehlt das Atomics-Objekt vollständig.