Maison  >  Article  >  Java  >  Impasse en Java

Impasse en Java

WBOY
WBOYoriginal
2024-08-30 15:40:06889parcourir

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

Comment fonctionne Deadlock ?

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.

Exemples de blocage en Java

Vous trouverez ci-dessous les exemples mentionnés :

Exemple n°1

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 :

Impasse en Java

Exemple n°2

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 :

Impasse en Java

Comment éviter les blocages en Java ?

Voici les directives qui aident à éviter les situations de blocage.

1. Évitez les verrous imbriqués

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.

2. Verrouillez uniquement ce qui est requis

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.

3. Évitez d'attendre indéfiniment

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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Article précédent:JavagetMethod()Article suivant:JavagetMethod()