Le bloc synchronisé Java est utilisé pour marquer des méthodes ou des blocs de code comme synchronisés. Les blocs synchronisés Java sont utilisés pour éviter les courses. Cet article présente le contenu suivant :
Mot-clé de synchronisation Java (synchronisé)
Synchronisation de méthode d'instance
Synchronisation de méthode statique
Bloc synchronisé en méthode d'instance
Bloc synchronisé en méthode statique
Exemple de synchronisation Java
Les blocs synchronisés en Java sont marqués par synchronisé. Un bloc synchronisé en Java est synchronisé sur un certain objet . Tous les blocs synchronisés sur un objet ne peuvent être saisis et exécutés que par un seul thread à la fois. Tous les autres threads en attente d'entrer dans ce bloc synchronisé seront bloqués jusqu'à ce que le thread exécutant ce bloc synchronisé quitte .
Il existe quatre blocs synchronisés différents :
Méthodes d'instance
Méthodes statiques
Blocs synchronisés dans les méthodes d'instance
Blocs synchronisés dans les méthodes statiques
Les blocs synchronisés ci-dessus sont tous synchronisés sur différents objets. Le bloc de synchronisation réellement nécessaire dépend de la situation.
Ce qui suit est une méthode d'instance synchronisée :
public synchronized void add(int value){ this.count += value; }
Notez le mot-clé synchronisé dans la déclaration de la méthode. Cela indique à Java que la méthode est synchrone.
La synchronisation des méthodes d'instance Java est synchronisée sur l'objet propriétaire de la méthode. De cette manière, la synchronisation des méthodes de chaque instance est synchronisée sur un objet différent, c'est-à-dire l'instance à laquelle appartient la méthode. Un seul thread peut s’exécuter dans un bloc synchronisé de méthode d’instance. S'il existe plusieurs instances, un thread peut effectuer des opérations dans un bloc synchronisé d'instance à la fois. Un thread par instance.
La synchronisation de méthode statique est la même que la méthode de synchronisation de méthode d'instance et utilise également le mot-clé synchronisé. La synchronisation de la méthode statique Java est la suivante :
public static synchronized void add(int value){ count += value; }
De même, le mot-clé synchronisé indique ici à Java que cette méthode est synchronisée.
La synchronisation des méthodes statiques fait référence à la synchronisation sur l'objet de classe où se trouve la méthode. Étant donné qu'une classe ne peut correspondre qu'à un seul objet de classe dans la machine virtuelle Java, un seul thread est autorisé à exécuter simultanément des méthodes de synchronisation statique dans la même classe.
Pour les méthodes statiques synchronisées dans différentes classes, un thread peut exécuter les méthodes statiques synchronisées dans chaque classe sans attendre. Quelle que soit la méthode statique synchronisée appelée dans la classe, une classe ne peut être exécutée que par un seul thread à la fois.
Parfois, vous n'avez pas besoin de synchroniser la méthode entière, mais une partie de celle-ci. Java peut synchroniser une partie d'une méthode.
Un exemple de bloc synchronisé dans une méthode Java asynchrone est le suivant :
public void add(int value){ synchronized(this){ this.count += value; } }
L'exemple utilise le constructeur de bloc synchronisé Java pour marquer un bloc de code comme synchronisé. Ce code s'exécute comme une méthode synchronisée.
Notez que le constructeur de bloc synchronisé Java entoure l'objet de parenthèses. Dans l'exemple ci-dessus, "this" est utilisé, qui est l'instance elle-même qui appelle la méthode add. L'objet entre parenthèses dans le constructeur synchronisé est appelé un objet moniteur. Le code ci-dessus utilise la synchronisation des objets de surveillance et la méthode d'instance synchronisée utilise l'instance de la méthode appelante elle-même comme objet de surveillance.
Un seul thread peut s'exécuter à la fois dans une méthode Java synchronisée avec le même objet moniteur.
Les deux exemples suivants synchronisent les objets d'instance qu'ils sont appelés, ils sont donc équivalents dans les effets d'exécution de synchronisation.
public class MyClass { public synchronized void log1(String msg1, String msg2){ log.writeln(msg1); log.writeln(msg2); } public void log2(String msg1, String msg2){ synchronized(this){ log.writeln(msg1); log.writeln(msg2); } } }
Dans l'exemple ci-dessus, un seul thread peut s'exécuter dans l'une ou l'autre méthode des deux blocs synchronisés à la fois.
Si le deuxième bloc de synchronisation n'est pas synchronisé sur cet objet instance, alors les deux méthodes peuvent être exécutées par le thread en même temps.
Similaire à ce qui précède, voici deux exemples de synchronisation de méthodes statiques. Ces méthodes sont synchronisées sur l'objet classe auquel appartient la méthode.
public class MyClass { public static synchronized void log1(String msg1, String msg2){ log.writeln(msg1); log.writeln(msg2); } public static void log2(String msg1, String msg2){ synchronized(MyClass.class){ log.writeln(msg1); log.writeln(msg2); } } }
Ces deux méthodes ne sont pas accessibles aux threads en même temps.
Si le deuxième bloc de synchronisation n'est pas synchronisé sur l'objet MyClass.class. Ensuite, ces deux méthodes sont accessibles par les threads en même temps.
Dans l'exemple suivant, deux threads sont démarrés, tous deux appelant la méthode add de la même instance de la classe Counter. La synchronisation étant effectuée sur l'instance à laquelle appartient la méthode, un seul thread peut accéder à la méthode en même temps.
public class Counter{ long count = 0; public synchronized void add(long value){ this.count += value; } } public class CounterThread extends Thread{ protected Counter counter = null; public CounterThread(Counter counter){ this.counter = counter; } public void run() { for(int i=0; i<10; i++){ counter.add(i); } } } public class Example { public static void main(String[] args){ Counter counter = new Counter(); Thread threadA = new CounterThread(counter); Thread threadB = new CounterThread(counter); threadA.start(); threadB.start(); } }
创建了两个线程。他们的构造器引用同一个Counter实例。Counter.add方法是同步在实例上,是因为add方法是实例方法并且被标记上synchronized关键字。因此每次只允许一个线程调用该方法。另外一个线程必须要等到第一个线程退出add()方法时,才能继续执行方法。
如果两个线程引用了两个不同的Counter实例,那么他们可以同时调用add()方法。这些方法调用了不同的对象,因此这些方法也就同步在不同的对象上。这些方法调用将不会被阻塞。如下面这个例子所示:
public class Example { public static void main(String[] args){ Counter counterA = new Counter(); Counter counterB = new Counter(); Thread threadA = new CounterThread(counterA); Thread threadB = new CounterThread(counterB); threadA.start(); threadB.start(); } }
注意这两个线程,threadA和threadB,不再引用同一个counter实例。CounterA和counterB的add方法同步在他们所属的对象上。调用counterA的add方法将不会阻塞调用counterB的add方法。
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!