Les unités d'exécution (ou threads) sont capables de s'exécuter simultanément en utilisant des ressources communes. Dans ce cas, il s'avère nécessaire de synchroniser les modifications apportées aux données, afin d'obtenir des valeurs cohérentes.
Deux utilisateurs agissant sur une variable au sein de threads distincts, simultanés et asynchrones, risqueraient de provoquer une dégradation du résultat, et dans le pire des cas un dysfonctionnement et un blocage (deadlock) du programme.
Le partage de données entre différents threads oblige le programmeur, à considérer l'état et l'activité de chacune des unités d'exécution et de gérer précisément l'accès concurrentiel aux ressources par les threads.
La plateforme Java possède un mécanisme de synchronisation des threads par l'obtention d'un moniteur. Ce mécanisme se dénomme l'exclusion mutuelle. Si plusieurs thrads tentent d'accéder simultanément à des portions de code synchronisées d'un objet particulier, alors un et un seul obtiendra le moniteur lui permettant d'exécuter le code synchronisé. Lorsque ce thread terminera le traitement de ce code, alors le moniteur se libérera afin qu'un autre thread puisse à son tour accédé à sa portion de code synchronisée. Ainsi, il devient impossible à des threads concurrents de modifier simultanément les données partagées d'un objet. L'intégrité des données est donc assurée par ce moyen.
Il existe deux moyens de synchroniser du code :
public synchronized void methode(){//...}
public synchronized void methode(){ synchronized(obj){ //Bloc de code } }
Sommairepublic class Synchronisation { private String nom; private String prenom; private static String[][] personnes = { { "Theodore", "Roosevelt" }, { "George", "Marshall" }, { "Omar", "Bradley" }, { "Dwight", "Einsenhower" }, { "George", "Patton" }, { "Norman", "Cota" }, { "Matthew", "Ridgway" }, { "Thomas", "Barton" }, { "Lawton", "Collins" }, { "Douglas", "MacArthur" } }; public synchronized void assigner(String nom, String prenom) { this.nom = nom; try { Thread.sleep((long) (Math.random() * 2000)); } catch (InterruptedException x) { } this.prenom = prenom; afficher(); } private void afficher() { String nom = Thread.currentThread().getName(); System.out.println(Thread.currentThread().getName() + " produit " + this.prenom + " " + this.nom); } public static void main(String[] args) { final Synchronisation sync = new Synchronisation(); for (int i = 0; i < personnes.length; i++) { final int indice = i; Runnable r = new Runnable() { public void run() { sync.assigner( personnes[indice][0], personnes[indice][1]); } }; Thread t = new Thread(r, "Thread-" + i); t.start(); try { Thread.sleep(500); } catch (InterruptedException x) { } } } } /* Affiche sans le modificateur synchronized Thread-1 produit Marshall George Thread-0 produit Roosevelt Omar Thread-3 produit Einsenhower George Thread-4 produit Patton Norman Thread-2 produit Bradley Norman Thread-5 produit Cota Thomas Thread-6 produit Ridgway Thomas Thread-7 produit Barton Lawton Thread-9 produit MacArthur Douglas Thread-8 produit Collins Douglas * Affiche avec le modificateur synchronized Thread-0 produit Roosevelt Theodore Thread-1 produit Marshall George Thread-2 produit Bradley Omar Thread-3 produit Einsenhower Dwight Thread-4 produit Patton George Thread-5 produit Cota Norman Thread-6 produit Ridgway Matthew Thread-7 produit Barton Thomas Thread-8 produit Collins Lawton Thread-9 produit MacArthur Douglas */