L'article partage 4 exemples d'explications détaillées de la synchronisation
1. Il faut ajouter des mots clés synchronisés
classe publique threadtest {public static void main (string [] args) {exemple example = new Example (); Thread t1 = new Thread1 (exemple); Thread T2 = nouveau Thread1 (exemple); t1.start (); t2.start (); }} Exemple de classe {public synchronisé void exhate () {for (int i = 0; i <5; ++ i) {try {Thread.Sleep (1000); } catch (InterruptedException e) {e.printStackTrace (); } System.out.println ("Excuse:" + i); }}} classe Thread1 étend Thread {Exemple privé Exemple; public thread1 (exemple exemple) {this.example = exemple; } @Override public void run () {example.excute (); }}Le résultat de sortie du mot clé synchronisé est le suivant
Un ensemble de 0-4 sera d'abord sorti, puis l'ensemble suivant sera sorti, et les deux threads seront exécutés en séquence.
Excuse: 0
Excuit: 1
Excuser: 2
Excuit: 3
Excuser: 4
Excuse: 0
Excuit: 1
Excuser: 2
Excuit: 3
Excuser: 4
Le résultat de sortie du mot clé synchronisé est le suivant
Deux threads exécutent la méthode d'excuit simultanément et simultanément
Excuse: 0
Excuse: 0
Excuit: 1
Excuit: 1
Excuser: 2
Excuser: 2
Excuit: 3
Excuit: 3
Excuser: 4
Excuser: 4
2. Situation multi-lancement de méthodes multiples
classe publique threadtest {public static void main (string [] args) {exemple example = new Example (); Thread t1 = new Thread1 (exemple); Thread T2 = nouveau Thread2 (exemple); t1.start (); t2.start (); }} Exemple de classe {public synchronisé void exhate () {for (int i = 0; i <5; ++ i) {try {Thread.Sleep (1000); } catch (InterruptedException e) {e.printStackTrace (); } System.out.println ("Excuse:" + i); }} public synchronisé void échape1 () {for (int i = 0; i <5; ++ i) {try {thread.sleep (1000); } catch (InterruptedException e) {e.printStackTrace (); } System.out.println ("excuse1:" + i); }}} classe Thread1 étend Thread {Exemple privé Exemple; public thread1 (exemple exemple) {this.example = exemple; } @Override public void run () {example.excute (); }} classe Thread2 étend Thread {Exemple privé Exemple; public thread2 (exemple exemple) {this.example = exemple; } @Override public void run () {example.excute1 (); }}Les résultats de l'exécution sont les suivants
La même chose est exécutée en séquence et un thread est exécuté avant l'exécution d'un autre thread.
Excuse: 0
Excuit: 1
Excuser: 2
Excuit: 3
Excuser: 4
Excut1: 0
Excut1: 1
Excut1: 2
Excut1: 3
exclusif1: 4
Si le mot-clé synchronisé est supprimé, les deux méthodes sont exécutées simultanément et n'ont aucune influence mutuelle.
Mais comme écrit dans l'exemple de sous-programme, même deux méthodes:
Le résultat d'exécution est toujours la sortie d'un thread puis l'exécution d'un autre thread.
illustrer:
Si un objet a plusieurs méthodes synchronisées et qu'un thread a entré une méthode synchronisée à un certain moment, alors d'autres threads ne peuvent accéder à aucune méthode synchronisée de l'objet avant l'exécution de la méthode.
en conclusion:
Lorsque le mot-clé synchronisé modifie une méthode, la méthode est appelée méthode de synchronisation.
Chaque objet en Java a une serrure ou un moniteur. Lorsqu'un thread accède à la méthode synchronisée d'un objet, l'objet est verrouillé, et aucun autre thread ne peut accéder à la méthode synchronisée de l'objet (se réfère ici à toutes les méthodes de synchronisation, pas seulement la même méthode). Ce n'est que lorsque le thread précédent termine la méthode d'exécution (ou lance une exception), le verrouillage de l'objet est libéré, de sorte que d'autres threads peuvent accéder à nouveau à la méthode synchronisée de l'objet.
Notez que l'objet est verrouillé à ce moment. S'il s'agit d'un objet différent, il n'y a pas de relation de restriction entre les objets.
Lorsque vous essayez de construire un deuxième objet de thread dans le code, un nouvel exemple d'objet est passé, alors il n'y a pas de restriction entre l'exécution des deux threads.
3. Méthode de synchronisation statique
Lorsqu'une méthode modifiée par mot-clé synchronisé est également modifiée par statique, il a été dit auparavant qu'une méthode de synchronisation non statique verra l'objet, mais la méthode statique n'appartient pas à l'objet, mais une classe, et elle verrouillera l'objet de classe de la classe où cette méthode est située.
classe publique threadtest {public static void main (string [] args) {exemple example = new Example (); Exemple Exemple2 = Nouveau exemple (); Thread t1 = new Thread1 (exemple); Thread T2 = nouveau Thread2 (Example2); t1.start (); t2.start (); }} Exemple de classe {public synchronisé statique void échappé () {for (int i = 0; i <5; ++ i) {try {Thread.Sleep (1000); } catch (InterruptedException e) {e.printStackTrace (); } System.out.println ("Excuse:" + i); }} public synchronisé statique void échappé1 () {for (int i = 0; i <5; ++ i) {try {Thread.Sleep (1000); } catch (InterruptedException e) {e.printStackTrace (); } System.out.println ("excuse1:" + i); }}} classe Thread1 étend Thread {Exemple privé Exemple; public thread1 (exemple exemple) {this.example = exemple; } @Override public void run () {example.excute (); }} classe Thread2 étend Thread {Exemple privé Exemple; public thread2 (exemple exemple) {this.example = exemple; } @Override public void run () {example.excute1 (); }}Les résultats de l'exécution sont les suivants
Excuse: 0
Excuit: 1
Excuser: 2
Excuit: 3
Excuser: 4
Excut1: 0
Excut1: 1
Excut1: 2
Excut1: 3
exclusif1: 4
S'il n'y a pas de modificateur statique et que deux threads transmettent différents objets, ils seront exécutés simultanément en même temps.
Donc, s'il s'agit d'une méthode statique (exécuter () et exécuter2 () ont toutes deux des mots clés statiques ajoutés), même si différents exemples d'objets sont transmis à deux threads, les deux threads sont toujours limités l'un de l'autre. Il faut d'abord être exécuté puis le suivant.
en conclusion:
Si une méthode synchronisée est statique, lorsqu'un thread accède à la méthode, il ne verrouille pas l'objet où se trouve la méthode synchronisée, mais l'objet de classe correspondant à la classe où se trouve la méthode synchronisée. En Java, peu importe le nombre d'objets d'une classe, ces objets correspondent à un objet de classe unique. Par conséquent, lorsqu'un thread accède à deux méthodes statiques et synchronisées de deux objets de la même classe, leur ordre d'exécution est également séquentiel, c'est-à-dire qu'un thread exécute d'abord la méthode et l'autre thread commence une fois l'exécution terminée.
4. Bloc synchronisé
synchronisé (objet)
{
}
Cela signifie que le fil verra l'objet objet lors de sa réalisation. (Notez que cet objet peut être un objet de n'importe quelle classe, ou vous pouvez utiliser ce mot-clé).
De cette façon, vous pouvez spécifier vous-même l'objet verrouillé.
classe publique threadtest {public static void main (string [] args) {exemple example = new Example (); Thread t1 = new Thread1 (exemple); Thread T2 = nouveau Thread2 (exemple); t1.start (); t2.start (); }} Exemple de classe {public void exhate () {synchronisé (this) {for (int i = 0; i <5; ++ i) {try {thread.sleep (1000); } catch (InterruptedException e) {e.printStackTrace (); } System.out.println ("Excuse:" + i); }}} public void shishen1 () {synchronisé (this) {for (int i = 0; i <5; ++ i) {try {thread.sleep (1000); } catch (InterruptedException e) {e.printStackTrace (); } System.out.println ("excuse1:" + i); }}}}}} classe Thread1 étend Thread {Exemple privé Exemple; public thread1 (exemple exemple) {this.example = exemple; } @Override public void run () {example.excute (); }} classe Thread2 étend Thread {Exemple privé Exemple; public thread2 (exemple exemple) {this.example = exemple; } @Override public void run () {example.excute1 (); }}Les résultats de l'exécution sont les suivants
Excuse: 0
Excuit: 1
Excuser: 2
Excuit: 3
Excuser: 4
Excut1: 0
Excut1: 1
Excut1: 2
Excut1: 3
exclusif1: 4
L'effet obtenu par l'exemple du programme 4 est le même que celui de l'exemple de programme 2. Les deux threads sont exécutés en séquence, plutôt que simultanément. Lorsqu'un thread s'exécute, l'objet objet est verrouillé et l'autre thread ne peut pas exécuter le bloc correspondant.
La méthode synchronisée est en fait équivalente à l'emballage de toutes les instructions dans la méthode avec un bloc synchronisé, puis en passant ce mot-clé dans les supports du bloc synchronisé. Bien sûr, s'il s'agit d'une méthode statique, l'objet de classe doit être verrouillé.
Peut-être que seulement quelques lignes de code dans une méthode impliqueront des problèmes de synchronisation des threads, de sorte que le bloc synchronisé contrôle l'accès de plusieurs threads plus granulaire que la méthode synchronisée. Seul le contenu du bloc synchronisé ne peut pas être accessible par plusieurs threads en même temps, et d'autres instructions dans la méthode sont toujours accessibles par plusieurs threads en même temps (y compris avant et après le bloc synchronisé).
en conclusion:
La méthode synchronisée est un contrôle simultané à grain grossier. À un certain moment, un seul thread peut exécuter la méthode synchronisée;
Le bloc synchronisé est un contrôle de concurrence à grain fin, qui synchronise uniquement le code dans le bloc. D'autres codes situés dans la méthode et autres que les blocs synchronisés peuvent être accessibles par plusieurs threads en même temps.
Ce qui précède concerne la méthode de synchronisation de bloc synchronisée de la programmation multithread Java. J'espère que cela sera utile à l'apprentissage de tous.