Cet article présente principalement l'explication détaillée et des exemples du verrouillage de synchronisation Java (synchronisé). Les amis qui en ont besoin peuvent se référer à
Explication détaillée et exemples du verrouillage de synchronisation Java (synchronisé)
La tranche de temps allouée par le CPU à chaque thread en Java est aléatoire. En Java, de nombreux threads partagent la même ressource. Par exemple, lors de la vente de billets de train, le billet de train est certain, mais la fenêtre de vente du train. les billets sont partout. Chaque fenêtre est équivalente à un fil de discussion. De nombreux fils de discussion partagent la ressource de tous les billets de train. Si deux threads utilisent cette ressource en même temps à un moment donné, les billets de train qu'ils retireront seront les mêmes (même numéro de siège), ce qui causera des problèmes aux passagers. Par exemple, le programme suivant :
package com.pakage.ThreadAndRunnable; public class Runnable_demo implements Runnable{ private int ticket=10; public Runnable_demo(){ } @Override public void run() { for(int i=0;i<20;i++){ if(this.ticket>0){ //休眠1s秒中,为了使效果更明显,否则可能出不了效果 try { Thread.sleep(1000); } catch (Exception e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"号窗口卖出:"+this.ticket--+"号票"); } } } public static void main(String args[]){ Runnable_demo demo=new Runnable_demo(); //基于火车票创建三个窗口 new Thread(demo,"a").start(); new Thread(demo,"b").start(); new Thread(demo,"c").start(); } }
Résultats d'exécution du programme :
Nous pouvons voir que la fenêtre c et la fenêtre b sont vendues Le billet n°10 a été acheté et les billets n°0 et -1 ont été vendus respectivement aux guichets A et B. La raison de cette situation est 1. Lorsque le thread c et le thread b ont ticket=10, après que le thread c ait retiré le ticket n°10, le ticket n'est pas encore arrivé et est réduit de 1, et le thread b prend sort le ticket. A ce moment, le ticket est toujours égal à 10. ; 2. Lorsque ticket=1, le thread c sort le ticket n°1, et avant que le ticket n'arrive, il est décrémenté de 1. Les threads a et b entrent. le ifdéclaration de jugement successivement, et le ticket est décrémenté de 1. , puis lorsque les threads a et b obtiennent des tickets, ils obtiennent les tickets n° 0 et -1.
Comment changer la situation ci-dessus ? Nous pouvons faire ceci : Quand un fil de discussion veut utiliser la ressource des billets de train, nous lui donnons un verrou et attendons qu'il fasse la chose après pour finir, donnez le verrou à un autre thread qui souhaite utiliser cette ressource . De cette façon, la situation ci-dessus ne se produira pas. Pour implémenter cette fonction de verrouillage, vous devez utiliser le mot-clé synchronisé.
Le mot-clé synchronisé a deux utilisations 1. Mettez-le avant le nom de la méthode pour former une méthode synchronisée ; 2. Mettez-le avant le bloc pour former un bloc synchronisé.
1. Utilisez la méthode de synchronisation pour modifier l'exemple ci-dessus en :
package com.pakage.ThreadAndRunnable; public class Runnable_demo implements Runnable{ private int ticket=10; public Runnable_demo(){ } @Override public void run() { for(int i=0;i<20;i++){ if(this.ticket>0){ //休眠1s秒中,为了使效果更明显,否则可能出不了效果 try { Thread.sleep(1000); } catch (Exception e) { e.printStackTrace(); } this.sale(); } } } public synchronized void sale(){ if(this.ticket>0){ System.out.println(Thread.currentThread().getName()+"号窗口卖出:"+this.ticket--+"号票"); } } public static void main(String args[]){ Runnable_demo demo=new Runnable_demo(); //基于火车票创建三个窗口 new Thread(demo,"a").start(); new Thread(demo,"b").start(); new Thread(demo,"c").start(); } }
Le résultat de sortie du programme est :
2. Utilisez le bloc de synchronisation pour modifier l'exemple ci-dessus :
package com.pakage.ThreadAndRunnable; public class Runnable_demo implements Runnable{ private int ticket=10; public Runnable_demo(){ } @Override public void run() { for(int i=0;i<20;i++){ <span style="color:#ff0000">synchronized</span>(this){ if(this.ticket>0){ //休眠1s秒中,为了使效果更明显,否则可能出不了效果 try { Thread.sleep(1000); } catch (Exception e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"号窗口卖出:"+this.ticket--+"号票"); } } } } public static void main(String args[]){ Runnable_demo demo=new Runnable_demo(); //基于火车票创建三个窗口 new Thread(demo,"a").start(); new Thread(demo,"b").start(); new Thread(demo,"c").start(); } }
Le résultat de sortie du programme :
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!