« Programmation Java/Processus légers et synchronisation » : différence entre les versions

Contenu supprimé Contenu ajouté
Aucun résumé des modifications
DannyS712 (discussion | contributions)
m <source> -> <syntaxhighlight> (phab:T237267)
Ligne 33 :
 
Exemple :
<sourcesyntaxhighlight lang="java">
public class MyThread extends Thread
{
Ligne 43 :
}
}
</syntaxhighlight>
</source>
Il est alors créé et démarré de la manière suivante :
<sourcesyntaxhighlight lang="java">
MyThread myth=new MyThread();
System.err.println("Démarrer le processus léger ...");
myth.start();
System.err.println("Le processus léger est démarré.");
</syntaxhighlight>
</source>
Il n'est pas toujours possible d'étendre la classe <code>Thread</code> car Java n'autorise qu'une classe de base.
Mais il est permis d'utiliser plusieurs interfaces.
Ligne 58 :
 
Exemple :
<sourcesyntaxhighlight lang="java">
public class MyClass extends AnotherClass
implements Runnable
Ligne 69 :
}
}
</syntaxhighlight>
</source>
Le processus léger est alors créé et démarré de la manière suivante :
<sourcesyntaxhighlight lang="java">
MyClass myclass=new MyClass ();
Thread th=new Thread(myclass); // <-- processus léger créé
Ligne 77 :
th.start();
System.err.println("Le processus léger est démarré.");
</syntaxhighlight>
</source>
== Actions sur un processus léger ==
 
Ligne 100 :
 
Exemple :
<sourcesyntaxhighlight lang="java">
th.join(); // InterruptedException à capturer
</syntaxhighlight>
</source>
 
=== Interrompre un processus léger ===
Ligne 118 :
 
La syntaxe est la suivante :
<sourcesyntaxhighlight lang="java">
... code non protégé ...
synchronized(objet) {
Ligne 124 :
}
... code non protégé ...
</syntaxhighlight>
</source>
Le code protégé n'est exécuté que par un seul processus léger à la fois, tant qu'il n'a pas terminé le bloc d'instruction.
 
Ligne 130 :
 
Le mot-clé <code>synchronized</code> peut également être utilisé dans la déclaration des méthodes :
<sourcesyntaxhighlight lang="java">
public synchronized void codeProtege() {
... code protégé ...
}
</syntaxhighlight>
</source>
est équivalent à :
<sourcesyntaxhighlight lang="java">
public void codeProtege() {
synchronized(this)
Ligne 143 :
}
}
</syntaxhighlight>
</source>
Pour une méthode statique (méthode de classe) :
<sourcesyntaxhighlight lang="java">
public class MyClass {
public synchronized static void codeProtege() {
Ligne 151 :
}
}
</syntaxhighlight>
</source>
est équivalent à :
<sourcesyntaxhighlight lang="java">
public class MyClass {
public static void codeProtege() {
Ligne 161 :
}
}
</syntaxhighlight>
</source>
 
=== Attente et signal ===
Ligne 179 :
 
Exemple :
<sourcesyntaxhighlight lang="java">
synchronized(myobj)
{
myobj.wait();
}
</syntaxhighlight>
</source>
 
Comme ces méthodes sont définies dans la classe <code>Object</code>, il est possible de les utiliser avec n'importe quel type d'objet, et donc les chaînes de caractères et les tableaux.
Ligne 191 :
Il est très courant d'être amené à protéger l'accès à une variable pour juste par exemple, une incrémentation sous condition, comparer et échanger deux valeurs, chercher et ajouter. Ces méthodes sont qualifiées d'atomiques. La solution la plus efficace consiste à utiliser les classes de la bibliothèque java.util.concurrent. Ces classes disposent de méthodes considérées comme toujours plus rapides en mode multi-thread que celles d'une liste synchronisée, prenons par exemple le cas des listes :
 
<sourcesyntaxhighlight lang="java">
String str;
Map<String,String> map=new HashMap<String,String>();
Ligne 199 :
synchronized { str=map.get("tutu");}
 
</syntaxhighlight>
</source>
...
<sourcesyntaxhighlight lang="java">
synchronized {
if (!map.containsKey("titi"))
bd.put("titi", "valeur exemple 3");
}
</syntaxhighlight>
</source>
 
Un autre thread ne peut pas effectuer de modification entre containsKey et put, du fait du verrou posé par l'instruction synchronized. Mais cette solution est en réalité peu efficace car elle contraint le plus souvent à protéger tous les accès à la liste, en lecture comme en écriture, alors que les accès en lectures multiples n'ont pas à être bloquants, seuls ceux en écriture devant l'être. La classe ConccurentHashMap possède un putIfAbsent. Il est possible de réimplanter cette caractéristique via la synchronisation sur deux valeurs, mais les classes fournies par java.util.concurrent sont, elles, exemptes de bugs.