Atomiques JavaScript
L'objet Atomics
L'objet Atomics fournit des opérations atomiques de bas niveau sur la mémoire partagée.
Il est utilisé avec SharedArrayBuffer et Typed Arrays pour partager des données entre les travailleurs.
Qu'est-ce que les Atomics ?
Lorsque plusieurs threads (par exemple, le thread principal et un ou plusieurs travailleurs) accèdent aux mêmes données, vous pouvez rencontrer des conditions de concurrence. Atomics aide à éviter ces conditions de concurrence en fournissant des opérations qui :
- Fonctionnent sur des tableaux typés partagés
- Sont effectuées de manière atomique (ne peuvent pas être interrompues en cours de route)
- Renvoient la valeur précédente de l'élément
L'objet Atomics est un objet global (comme Math) avec des méthodes statiques telles que Atomics.load(), Atomics.store(), Atomics.add(), et plus encore.
Remarque
Les Atomics sont une fonctionnalité avancée.
Vous utilisez généralement les Atomics lorsque vous travaillez avec :
- Web Workers
- Threads de travail
- Mémoire partagée
Exigences
Pour utiliser les Atomics, vous avez besoin de :
- Un
SharedArrayBuffer - Un tableau typé qui utilise le tampon partagé (par exemple,
Int32Array) - Un ou plusieurs travailleurs (ou threads) qui partagent le même tampon
SharedArrayBuffer soit activé sur le web. Utilisation de base des Atomics
Exemple : Création d'un tableau typé partagé
Créez un tampon partagé et un tableau d'entiers partagé :
const buffer = new SharedArrayBuffer(4 * Int32Array.BYTES_PER_ELEMENT);
// Tableau d'entiers partagé avec 4 éléments
const sharedArray = new Int32Array(buffer);
// Initialiser le tableau
sharedArray[0] = 10;
sharedArray[1] = 20;
sharedArray[2] = 30;
sharedArray[3] = 40;
Lecture et écriture atomiques
Utilisez Atomics.load() pour lire et Atomics.store() pour écrire un élément dans un tableau typé partagé.
Exemple : Atomics.load() et Atomics.store()
var buffer = new SharedArrayBuffer(4 * Int32Array.BYTES_PER_ELEMENT);
var sharedArray = new Int32Array(buffer);
// Stocker une valeur de manière atomique
Atomics.store(sharedArray, 0, 123);
// Charger la valeur de manière atomique
var value = Atomics.load(sharedArray, 0);
console.log("Valeur :", value); // Valeur : 123 Remarque
Atomics.store() renvoie la valeur que vous avez stockée.
Atomics.load() renvoie la valeur actuelle de l'élément.
Addition et soustraction atomiques
Atomics.add() et Atomics.sub() modifient une valeur et renvoient la valeur précédente.
Exemple : Atomics.add()
var buffer = new SharedArrayBuffer(4 * Int32Array.BYTES_PER_ELEMENT);
var sharedArray = new Int32Array(buffer);
sharedArray[0] = 5;
var oldValue = Atomics.add(sharedArray, 0, 3);
console.log("Ancien :", oldValue); // Ancien : 5
console.log("Nouveau :", sharedArray[0]);// Nouveau : 8
Exemple : Atomics.sub()
var buffer = new SharedArrayBuffer(4 * Int32Array.BYTES_PER_ELEMENT);
var sharedArray = new Int32Array(buffer);
sharedArray[0] = 10;
var oldValue = Atomics.sub(sharedArray, 0, 4);
console.log("Ancien :", oldValue); // Ancien : 10
console.log("Nouveau :", sharedArray[0]);// Nouveau : 6
Échange atomique et CompareExchange
Atomics.exchange() définit une nouvelle valeur et renvoie l'ancienne. Atomics.compareExchange() ne définit une nouvelle valeur que si la valeur actuelle est égale à une valeur attendue donnée.
Exemple : Atomics.exchange()
var buffer = new SharedArrayBuffer(4 * Int32Array.BYTES_PER_ELEMENT);
var sharedArray = new Int32Array(buffer);
sharedArray[0] = 1;
var oldValue = Atomics.exchange(sharedArray, 0, 99);
console.log("Ancien :", oldValue); // Ancien : 1
console.log("Nouveau :", sharedArray[0]); // Nouveau : 99
Exemple : Atomics.compareExchange()
var buffer = new SharedArrayBuffer(4 * Int32Array.BYTES_PER_ELEMENT);
var sharedArray = new Int32Array(buffer);
sharedArray[0] = 10;
// Remplacer 10 par 20 uniquement si la valeur actuelle est 10
var oldValue = Atomics.compareExchange(sharedArray, 0, 10, 20);
console.log("Ancien :", oldValue); // Ancien : 10
console.log("Nouveau :", sharedArray[0]); // Nouveau : 20
// Maintenant, cela ne changera PAS car la valeur attendue ne correspond pas
oldValue = Atomics.compareExchange(sharedArray, 0, 10, 30);
console.log("Ancien :", oldValue); // Ancien : 20
console.log("Nouveau :", sharedArray[0]); // Nouveau : 20
Atomics.wait() et Atomics.notify()
Atomics.wait() (dans les travailleurs) peut mettre un thread en veille jusqu'à ce que la valeur à une position change, et Atomics.notify() réveille un ou plusieurs threads endormis.
Atomics.wait() ne peut être utilisé que dans des contextes de travail (pas sur le thread principal) dans les navigateurs. Exemple : Travailleur attendant une valeur
Thread principal (simplifié) :
// main.js
var buffer = new SharedArrayBuffer(4);
var sharedArray = new Int32Array(buffer);
sharedArray[0] = 0;
var worker = new Worker("worker.js");
// Envoyer le tampon partagé au travailleur
worker.postMessage(buffer);
// Simuler un travail, puis définir la valeur et notifier le travailleur
setTimeout(function() {
Atomics.store(sharedArray, 0, 1);
Atomics.notify(sharedArray, 0, 1); // réveiller 1 travailleur
}, 1000);
Travailleur (worker.js) :
// worker.js
onmessage = function(e) {
var buffer = e.data;
var sharedArray = new Int32Array(buffer);
console.log("Travailleur en attente...");
var result = Atomics.wait(sharedArray, 0, 0); // attendre que la valeur soit 0
console.log("Travailleur réveillé, résultat =", result);
console.log("Nouvelle valeur :", Atomics.load(sharedArray, 0));
};
Référence complète des Atomics
Révisé en décembre 2025
| Méthode | Description |
|---|---|
| load(typedArray, index) | Lit et renvoie la valeur à l'index. |
| store(typedArray, index, value) | Stocke la valeur à l'index et la renvoie. |
| add(typedArray, index, value) | Ajoute la valeur à l'élément et renvoie l'ancienne valeur. |
| sub(typedArray, index, value) | Soustrait la valeur et renvoie l'ancienne valeur. |
| and(typedArray, index, value) | Effectue un ET bit à bit avec la valeur et renvoie l'ancienne valeur. |
| or(typedArray, index, value) | Effectue un OU bit à bit avec la valeur et renvoie l'ancienne valeur. |
| xor(typedArray, index, value) | Effectue un OU exclusif bit à bit avec la valeur et renvoie l'ancienne valeur. |
| exchange(typedArray, index, value) | Remplace la valeur à l'index et renvoie l'ancienne valeur. |
| compareExchange(typedArray, index, expected, value) | Remplace la valeur à l'index par la valeur si la valeur actuelle est attendue. Renvoie l'ancienne valeur. |
| wait(typedArray, index, value, timeout?) | (Travailleur uniquement) Bloque le thread appelant jusqu'à ce que l'élément change ou que le délai expire. |
| notify(typedArray, index, count) | Réveille les threads endormis qui attendent sur l'index. |
- Les Atomics sont destinés à la communication entre threads utilisant la mémoire partagée
- Vous les utilisez avec SharedArrayBuffer et Typed Arrays
- Les opérations Atomics ne peuvent pas être interrompues par d'autres threads
- Utilisez les Atomics uniquement lorsque vous avez besoin d'une synchronisation de bas niveau
- La plupart des codes JavaScript n'ont pas besoin des Atomics