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 :

  • La synchronisation des méthodes critiques par l'intermédiaire du modificateur synchronized.
    public synchronized void methode(){//...}
  • La synchronisation d'un bloc de code par sa délimitation au moyen du mot clé synchronized auquel est associé un objet.
    public synchronized void methode(){
        synchronized(obj){
            //Bloc de code
        }
    }
public 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
*/
Sommaire