En Java, le travail avec les threads est réalisé à travers les classes Thread, Runnable et du paquet java.util.concurrent. Pour organiser la sécurité des threads, différents mécanismes de synchronisation sont utilisés :
synchronized) permettent à plusieurs threads d'accéder à des données communes sans concurrence.ReentrantLock, Semaphore, AtomicInteger, ConcurrentHashMap) offrent des moyens de synchronisation plus flexibles.Exemple de synchronisation :
public class Counter { private int count = 0; public synchronized void increment() { count++; } public int getCount() { return count; } }
Exemple utilisant des classes atomiques :
import java.util.concurrent.atomic.AtomicInteger; public class AtomicCounter { private AtomicInteger count = new AtomicInteger(0); public void increment() { count.incrementAndGet(); } public int getCount() { return count.get(); } }
Le mot-clé volatile garantit-il la sécurité des threads lors de l'incrémentation d'un compteur de type int ?
Réponse : Non. volatile assure seulement la visibilité de la valeur entre les threads, mais pas l'atomicité des opérations. L'incrémentation n'est pas une opération atomique (count++ consiste en lecture, augmentation et écriture), donc il peut y avoir des pertes de données. Pour un incrément sécurisé par les threads, une synchronisation ou des classes comme AtomicInteger sont nécessaires.
volatile int count = 0; // count++ n'est pas sécurisé par les threads !
Histoire
Dans un magasin en ligne, le compte de bonus était mis à jour via un compteur volatile. Sous la charge de milliers d'utilisateurs commandant des produits, une partie des bonus se perdait en raison de la concurrence des threads sur count++.
Histoire
Un employé a utilisé une liste ArrayList ordinaire comme tampon commun entre le producteur et le consommateur dans une application multi-thread, ce qui a conduit à des ConcurrentModificationException. La solution a été d'utiliser des blocs synchronisés ou de remplacer par CopyOnWriteArrayList.
Histoire
Dans le traitement des paiements, un développeur exécutait l'opération "vérifier et déduire le montant" via deux méthodes non liées. Dans des conditions de forte charge, cela entraînait des doubles débits jusqu'à l'implémentation de transactions atomiques et de verrous.