Variables atomiques : mises à jour sans verrou
Utilisez AtomicInteger, AtomicLong et AtomicReference pour créer des compteurs sûrs vis-à-vis des threads, sans verrous.
Variables atomiques : mises à jour sans verrou est une leçon Java Academy gratuite sur CoddyKit. Ceci est la leçon 3 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Java Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Java Academy comprend 4 leçons au total.
Le problème des opérations non atomiques
L’incrémentation simple count++ n’est NOT sûre vis-à-vis des fils d’exécution : elle comporte trois opérations : lire, additionner et écrire. Des fils d’exécution concurrents peuvent les entrelacer, ce qui provoque la perte de mises à jour. Les variables atomiques résolvent ce problème sans verrous.
// UNSAFE:
int count = 0;
// Thread A reads count=0, Thread B reads count=0
// Both write 1 — second update lost!
count++; // NOT thread-safe
// SAFE:
import java.util.concurrent.atomic.*;
AtomicInteger atomicCount = new AtomicInteger(0);
atomicCount.incrementAndGet(); // atomic, lock-freePrincipes d’AtomicInteger
AtomicInteger fournit des opérations sur les entiers qui sont garanties atomiques grâce aux instructions CPU de comparaison-échange (CAS) — aucun verrou n’est nécessaire.
AtomicInteger counter = new AtomicInteger(0);
counter.set(10); // set to 10
System.out.println(counter.get()); // 10
int prev = counter.getAndIncrement(); // returns 10, sets to 11
int curr = counter.incrementAndGet(); // sets to 12, returns 12
counter.addAndGet(5); // adds 5, returns 17
counter.decrementAndGet(); // subtracts 1, returns 16compareAndSet : l’opération CAS
compareAndSet(expected, update) met à jour la valeur de manière atomique uniquement si elle est actuellement égale à la valeur attendue. La méthode renvoie true en cas de réussite. C’est le fondement de tous les algorithmes sans verrou.
AtomicInteger ai = new AtomicInteger(5);
boolean updated = ai.compareAndSet(5, 10); // current==5? set to 10
System.out.println(updated); // true
System.out.println(ai.get()); // 10
boolean failed = ai.compareAndSet(5, 20); // current==10, not 5 → fails
System.out.println(failed); // false
System.out.println(ai.get()); // still 10AtomicLong pour les compteurs
AtomicLong est l’équivalent sur 64 bits. Il est souvent utilisé pour les générateurs de séquences et les compteurs de consultations :
AtomicLong seq = new AtomicLong(0);
// Thread-safe sequence generator:
long nextId() {
return seq.incrementAndGet();
}
System.out.println(nextId()); // 1
System.out.println(nextId()); // 2
System.out.println(nextId()); // 3AtomicBoolean
Indicateur booléen sûr vis-à-vis des fils d’exécution. Il est souvent utilisé pour une initialisation unique ou pour signaler un arrêt :
AtomicBoolean initialized = new AtomicBoolean(false);
void initOnce() {
// compareAndSet: only first caller succeeds
if (initialized.compareAndSet(false, true)) {
System.out.println("Initializing...");
// perform expensive init
} else {
System.out.println("Already initialized");
}
}AtomicReference
AtomicReference<V> fournit des mises à jour atomiques d’une référence d’objet. Il est utilisé pour implémenter des structures de données sans verrou :
import java.util.concurrent.atomic.*;
record Config(String host, int port) {}
AtomicReference<Config> configRef =
new AtomicReference<>(new Config("localhost", 8080));
// Hot-swap the configuration atomically:
Config oldConfig = configRef.get();
Config newConfig = new Config("prod.example.com", 443);
boolean swapped = configRef.compareAndSet(oldConfig, newConfig);
System.out.println(swapped); // true
System.out.println(configRef.get()); // Config[host=prod.example.com, port=443]updateAndGet / getAndUpdate
Appliquez une fonction de manière atomique au moyen d’une boucle interne de nouvelles tentatives CAS :
AtomicInteger value = new AtomicInteger(10);
// Apply function atomically: square the value
int newVal = value.updateAndGet(x -> x * x);
System.out.println(newVal); // 100
// Get old, then apply:
int old = value.getAndUpdate(x -> x + 1);
System.out.println(old); // 100
System.out.println(value.get()); // 101accumulateAndGet
Combinez la valeur actuelle avec une valeur donnée au moyen d’une fonction :
AtomicInteger max = new AtomicInteger(0);
// Keep running maximum:
max.accumulateAndGet(42, Math::max); // max(0, 42) = 42
max.accumulateAndGet(15, Math::max); // max(42, 15) = 42
max.accumulateAndGet(99, Math::max); // max(42, 99) = 99
System.out.println(max.get()); // 99LongAdder pour les compteurs fortement sollicités
En cas de forte contention entre les fils d’exécution, les nouvelles tentatives CAS d’AtomicLong peuvent dégrader les performances. LongAdder utilise plusieurs cellules pour réduire la contention :
import java.util.concurrent.atomic.*;
LongAdder adder = new LongAdder();
// Multiple threads can call add() with minimal contention:
adder.increment();
adder.add(5);
adder.increment();
System.out.println(adder.sum()); // 7
// Note: sum() is NOT atomic with add() — use only when no concurrent addsTableaux atomiques
AtomicIntegerArray et AtomicLongArray fournissent des opérations atomiques sur les éléments individuels d’un tableau :
AtomicIntegerArray arr = new AtomicIntegerArray(5);
arr.set(0, 10);
arr.incrementAndGet(0);
arr.compareAndSet(2, 0, 42); // index 2: if 0, set 42
System.out.println(arr.get(0)); // 11
System.out.println(arr.get(2)); // 42Quand utiliser les variables atomiques plutôt que les verrous
Utilisez les variables atomiques lorsque :
- Les mises à jour portent sur une seule variable (compteurs, indicateurs, références)
- La contention est faible
- Les performances sans verrou sont importantes
Utilisez des verrous lorsque :
- Plusieurs variables doivent être mises à jour de manière atomique
- Une logique conditionnelle complexe est nécessaire
- La contention est très élevée (les nouvelles tentatives CAS dégradent les performances)
Vérification rapide
Que garantit compareAndSet(expected, update) ?
Récapitulatif : variables atomiques
Points essentiels :
- Les types atomiques utilisent les instructions CPU CAS — sans verrou et sûres vis-à-vis des fils d’exécution
- AtomicInteger/Long/Boolean/Reference assurent l’atomicité d’une seule variable
- compareAndSet est le fondement des algorithmes sans verrou
- updateAndGet/accumulateAndGet permettent des mises à jour fonctionnelles
- LongAdder convient aux scénarios de compteurs fortement sollicités
Questions Fréquemment Posées
La leçon « Variables atomiques : mises à jour sans verrou » est-elle gratuite ?
Oui — le texte complet de « Variables atomiques : mises à jour sans verrou » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Java Academy, passe à CoddyKit PRO. Le cours Java Academy comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « Variables atomiques : mises à jour sans verrou » ?
Utilisez AtomicInteger, AtomicLong et AtomicReference pour créer des compteurs sûrs vis-à-vis des threads, sans verrous. Tu pratiques Java Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer Java Academy ?
Aucune expérience préalable n'est requise. Java Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 3 sur 4.
Combien de temps prend la leçon « Variables atomiques : mises à jour sans verrou » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon Java Academy ?
Oui. Chaque leçon Java Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- ReentrantLock et synchronized
- ReadWriteLock pour les scénarios lecteur-rédacteur
- Variables atomiques : mises à jour sans verrou
- StampedLock et lectures optimistes