En Java, Deadlock est une situation de multithreading dans laquelle le thread 1 attend un verrou d'objet obtenu par le thread 2 et le thread 2 attend un verrou d'objet obtenu par le thread 1. Ici, le thread 1 et le thread 2 s'attendent l'un l'autre. pour libérer le verrou. Les programmes multithread en Java peuvent provoquer un blocage car le mot-clé synchronisé bloque le thread en cours d'exécution en attendant un moniteur ou un verrou lié à l'objet mentionné. Voyons le fonctionnement et les exemples de Deadlock dans les sections suivantes.
Commencez votre cours de développement de logiciels libres
Développement Web, langages de programmation, tests de logiciels et autres
Comme indiqué, la méthode synchronisée peut verrouiller une partie particulière du code. Pour chaque objet en Java, un verrou sera présent, et la synchronisation est une technique permettant de verrouiller une fonction ou un bloc de code pour garantir qu'un seul thread peut accéder à cette fonction ou à ce bloc de code à la fois.
Lorsqu'un thread spécifique doit exécuter une fonction synchronisée, il tente d'abord d'obtenir le verrou. Dans le même temps, si un autre thread a déjà reçu le verrou, le premier thread attend que le thread 2 libère le verrou. Même si la synchronisation évite les problèmes d'incohérence des données, il existe un problème de synchronisation.
Supposons qu'il y ait 2 fils de discussion, « Thread 1 » et « Thread 2 ». Le thread 1 a atteint le verrou de l'objet 1 et le thread 2 a atteint le verrou de l'objet 2. Le thread 1, qui exécute la méthode 1, veut atteindre le verrou sur l'objet 2. Cependant, le thread 2 atteint déjà le verrou sur l'objet 2.
De plus, le thread 2 doit également atteindre le verrou sur l'objet 1 ; cependant, le thread 1 a un verrou sur l'objet 1. Ici, les deux threads, Thread 1 et Thread 2, ne peuvent pas terminer leur exécution et attendre indéfiniment le verrou. Cette situation est appelée Deadlock.
Vous trouverez ci-dessous les exemples mentionnés :
Programme Java pour implémenter Deadlock.
Code :
public class DeadLockExample { //main method public static void main(String[] args) throws InterruptedException { //create three objects 1, 2 and 3 Object o1 = new Object(); Object o2 = new Object(); Object o3 = new Object(); //create three threads 1, 2 and 3 Thread th1 = new Thread(new SynchronizationThread(o1, o2), "thread 1"); Thread th2 = new Thread(new SynchronizationThread(o2, o3), "thread 2"); Thread th3 = new Thread(new SynchronizationThread(o3, o1), "thread 3"); //start thread 1 th1.start(); //thread sleeps for 5000 seconds Thread.sleep(5000); //start thread 2 th2.start(); //thread sleeps for 5000 seconds Thread.sleep(5000); //start thread 3 th3.start(); } } class SynchronizationThread implements Runnable { private Object o1; private Object o2; public SynchronizationThread(Object o1, Object o2){ this.o1=o1; this.o2=o2; } //function run @Override public void run() { //store the name of the thread String nm = Thread.currentThread().getName(); System.out.println( nm + " attaining lock on "+ o1 ) ; synchronized (o1) { System.out.println( nm + " attained lock on "+ o1 ) ; work(); System.out.println( nm + " attaining lock on "+ o2 ) ; synchronized (o2) { System.out.println( nm + " attained lock on "+ o2 ); work(); } System.out.println( nm + " released lock on "+ o2 ) ; } System.out.println( nm + " released lock on "+ o1 ) ; System.out.println( nm + " completed execution.") ; } //function work private void work() { try { //thread sleeps Thread.sleep(30000); } //catch the exception catch (InterruptedException exc) { exc.printStackTrace(); } } }
Sortie :
Dans ce programme, 3 threads en cours d'exécution partagent une ressource et s'exécutent de manière à atteindre le verrouillage sur l'objet 1, mais lorsqu'ils tentent d'atteindre le verrouillage sur l'objet 2, ils passent dans un état d'attente. Pour éviter le blocage, vous pouvez réécrire le code comme suit.
Code :
public class DeadLockExample { public static void main(String[] args) throws InterruptedException { Object o1 = new Object(); Object o2 = new Object(); Object o3 = new Object(); Thread th1 = new Thread(new SynchronizationThread(o1, o2), "thread 1"); Thread th2 = new Thread(new SynchronizationThread(o2, o3), "thread 2"); Thread th3 = new Thread(new SynchronizationThread(o3, o1), "thread 3"); //start thread 1, 2 and 3 th1.start(); //thread sleeps for 5000 seconds Thread.sleep(5000); th2.start(); //thread sleeps for 5000 seconds Thread.sleep(5000); th3.start(); } } class SynchronizationThread implements Runnable{ private Object o1; private Object o2; public SynchronizationThread(Object o1, Object o2){ this.o1=o1; this.o2=o2; } //function run @Override public void run() { //store the name of the thread String nm = Thread.currentThread().getName(); System.out.println( nm + " attaining lock on "+ o1 ) ; synchronized (o1) { System.out.println( nm + " attained lock on "+ o1 ) ; work(); } System.out.println( nm + " released lock on "+ o1 ) ; System.out.println( nm + " acquiring lock on " + o2 ); synchronized (o2) { System.out.println( nm + " attained lock on "+ o2 ); work(); } System.out.println( nm + " released lock on "+ o2 ) ; System.out.println( nm + " released lock on "+ o1 ) ; System.out.println( nm + " completed execution.") ; } //function work private void work() { try { //thread sleeps Thread.sleep(30000); } //catch the exception catch (InterruptedException exc) { exc.printStackTrace(); } } }
Sortie :
Voici les directives qui aident à éviter les situations de blocage.
Les verrous imbriqués sont l'une des causes courantes de blocages. Ne verrouillez pas une autre ressource si elle en contient déjà une pour éviter un blocage. Si l'utilisateur travaille avec un seul objet, il est impossible de provoquer un blocage.
Les gens recommandent de verrouiller uniquement les ressources nécessaires. Cependant, certains utilisateurs peuvent tenter de verrouiller des ressources même lorsqu'elles ne sont pas nécessaires.
Un blocage se produit si 2 threads s'attendent pour se terminer indéfiniment à l'aide de la jointure de thread. Si le fil doit attendre que d'autres fils se terminent, il est bon d'utiliser join avec le temps maximum nécessaire pour attendre que le fil se termine.
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!