Un bloc synchronisé Java rend une méthode ou un bloc de code synchronisé. Des blocs synchronisés Java peuvent être utilisés pour éviter les conditions statiques. Les blocs synchronisés en Java sont marqués à l'aide du mot-clé synchronisé. Un bloc synchronisé en Java est synchronisé sur certains objets. Tous les blocs synchronisés sur tous les objets ne peuvent être exécutés que par un seul thread à la fois. Tous les autres threads essayant d'entrer dans le bloc synchronisé sont bloqués jusqu'à ce que le thread à l'intérieur du bloc synchronisé quitte le bloc.
Le mot-clé synchronisé peut être utilisé pour marquer quatre types de blocs différents :
Méthode d'instance
Méthode statique
Bloc de code dans la méthode d'instance
Bloc de code dans la méthode statique
Ces blocs sont synchronisés dans différents objets. Le type de bloc de synchronisation dont vous avez besoin dépend du scénario spécifique.
Méthodes d'instance synchronisées
Voici un exemple :
Notez le mot-clé synchronisé dans la vie de la méthode de utiliser. Cela indique à Java que cette méthode est synchronisée. Une méthode d'instance synchronisée en Java est synchronisée sur l'objet instance appartenant à cette méthode. Ainsi, chaque instance a sa méthode de synchronisation synchronisée sur un objet différent : sa propre instance. Un seul thread peut exécuter une méthode d'instance synchronisée, puis un thread peut exécuter une méthode d'instance synchronisée une par une. Un thread par instance.
Méthodes statiques synchroniséespublic synchronized void add(int value){ this.count += value; }
Les méthodes statiques sont marquées comme synchronisées tout comme les méthodes d'instance à l'aide du mot-clé synchronisé. Voici un exemple :
Il y a aussi un mot-clé synchronisé ici pour indiquer à Java que cette méthode est synchronisée. Les méthodes statiques synchronisées sont synchronisées sur l'objet classe de la classe à laquelle appartient la méthode statique. Etant donné qu'un seul objet de classe existe pour chaque classe dans la machine virtuelle Java, un seul thread peut exécuter une méthode statique synchronisée de la même classe.
Si cette méthode synchronisée statique est située dans différentes classes, alors un thread peut exécuter la méthode synchronisée statique interne de chaque classe. Threads de chaque classe, quelle que soit la méthode de synchronisation statique qu'ils appellent.public static synchronized void add(int value){ count += value; }
Blocs synchronisés dans les méthodes d'instance
Vous ne pouvez pas synchroniser l'intégralité de la méthode. Parfois, il est préférable de synchroniser certaines parties d'une méthode. Les blocs synchronisés Java à l’intérieur des méthodes rendent cela possible.
Voici un exemple :
Cet exemple utilise des blocs de synchronisation Java pour construire un bloc de code synchronisé. S'il s'agit d'une méthode synchrone, cette méthode sera exécutée.
Notez comment ce bloc de synchronisation Java est construit avec des parties d'un objet. Dans cet exemple, "this" est utilisé, qui est l'instance de la méthode add appelée. L'objet entre parenthèses d'acceptation construit par synchronisation est appelé un objet moniteur. Ce code suppose que l'objet moniteur sera synchrone. Une méthode d'instance synchronisée utilise l'objet auquel elle appartient comme objet de surveillance.
Un seul thread peut s'exécuter dans un bloc Java synchronisé du même objet surveillé.
public void add(int value){ synchronized(this){ this.count += value; } }Un seul thread peut donc exécuter l'un des deux blocs synchronisés dans cet exemple. Il existe un deuxième bloc de synchronisation synchronisé sur un objet différent pour cela, et un thread ne peut alors exécuter qu'une seule méthode interne à la fois.
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); } } }Bloc synchronisé en méthode statique
Voici deux instances identiques en méthode statique. Ces méthodes sont synchronisées dans l'objet classe de la classe à laquelle appartient cette méthode :
Un seul thread peut exécuter l'une ou l'autre méthode en même temps. Il existe un deuxième bloc de synchronisation qui est synchronisé sur un objet différent, pour MyClass.class, et ensuite un thread ne peut exécuter qu'une seule méthode interne à la fois.
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); } } }Instance de synchronisation Java
Voici une instance qui démarre deux threads et ils appellent tous les deux la méthode add de la même instance de Counter. Un seul thread peut appeler la méthode add d'une même instance à la fois, car cette méthode est synchronisée sur l'instance à laquelle elle appartient :
public class Counter{ long count = 0; public synchronized void add(long value){ this.count += value; } }
Deux fils de discussion sont créés. Deux instances Counter identiques sont transmises à leurs constructeurs. La méthode add est synchronisée sur l'instance car la méthode add est une méthode d'instance et marquée comme synchronisée. Par conséquent, un seul thread à la fois peut appeler cette méthode add. Les autres threads attendront que le premier thread quitte la méthode add avant de pouvoir s'exécuter.
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); } } }Si deux threads font référence à deux instances Counter distinctes, il n'y aura aucun problème pour appeler la méthode add en même temps. Cet appel se fera sur un objet différent, donc cet appel de méthode sera également synchronisé sur un objet différent (l'objet qui appartient à cette méthode). Cet appel ne bloquera donc pas. Voici un exemple :
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(); } }
注意这两个线程,他们不再引用相同的实例。counterA和counterB的add方法同步在它们自己的实例上。因此不会堵塞。
Java并发工具
这个synchronized机制是java的第一个途径对于访问同步访问被多线程共享的对象。但是这个synchronized机制不是最高级的。那就是为什么Java 5提供了一个并发工具类的集合去帮助开发者实现更细粒度的并发控制相对于synchronized而言。
以上就是Java同步代码块的详细实例代码介绍的内容,更多相关内容请关注PHP中文网(www.php.cn)!