Maison  >  Article  >  Java  >  Comment réparer : erreur de concurrence Java : évitement des blocages

Comment réparer : erreur de concurrence Java : évitement des blocages

PHPz
PHPzoriginal
2023-08-19 13:54:321395parcourir

Comment réparer : erreur de concurrence Java : évitement des blocages

Comment résoudre : Erreur de concurrence Java : éviter les blocages

Introduction :

Dans le développement de programmes Java, la concurrence multithread est essentielle. Cependant, la programmation simultanée pose également certains problèmes, l'un des problèmes les plus courants et potentiellement graves étant le blocage. Le blocage fait référence à une situation dans laquelle deux threads ou plus détiennent les ressources requises l'un par l'autre, mais ne peuvent pas continuer l'exécution car l'autre partie ne libère pas les ressources. Cet article explorera comment résoudre les problèmes de blocage dans les erreurs de concurrence en Java et fournira quelques exemples de code.

1. Comprendre les causes de l'impasse :

Avant de résoudre le problème de l'impasse, vous devez d'abord comprendre la cause de l'impasse. Un blocage se produit généralement lorsque plusieurs threads sont en concurrence pour plusieurs ressources en même temps. Un blocage se produit lorsque deux threads ou plus s'attendent pour libérer une ressource requise. Voici un exemple de code simple :

class Resource {
    private String name;

    public Resource(String name) {
        this.name = name;
    }

    public synchronized void doSomething() {
        System.out.println(name + " is doing something.");
    }

    public synchronized void doAnotherthing(Resource otherResource) {
        System.out.println(name + " is doing anotherthing.");
        otherResource.doSomething();
    }
}

public class DeadlockExample {
    public static void main(String[] args) {
        Resource resource1 = new Resource("Resource1");
        Resource resource2 = new Resource("Resource2");

        Thread t1 = new Thread(() -> {
            resource1.doAnotherthing(resource2);
        });

        Thread t2 = new Thread(() -> {
            resource2.doAnotherthing(resource1);
        });

        t1.start();
        t2.start();
    }
}

Dans l'exemple ci-dessus, il y a deux ressources resource1 et resource2. Deux threads t1 et t2 sont créés dans la méthode main, et la méthode doAnotherthing de la ressource est appelée respectivement . Dans le thread t1, il appelle la méthode doAnotherthing de resource1 et passe resource2 en tant que paramètre. Dans le thread t2, il appelle la méthode doAnotherthing de resource2 et passe resource1 en tant que paramètre. resource1resource2。在main方法中创建了两个线程t1t2,并分别调用资源的doAnotherthing方法。在t1线程中,它调用resource1doAnotherthing方法,并传入resource2作为参数。在t2线程中,它调用resource2doAnotherthing方法,并传入resource1作为参数。

由于这两个线程互相等待对方释放所需的资源,所以会发生死锁。当然,这只是一个简单的示例,实际场景中可能包含更多资源和线程。

二、解决死锁问题:

  1. 预防死锁:

要预防死锁,首先需要了解死锁发生的原因。在上面的示例代码中,死锁是由于线程对资源的获取顺序不一致导致的。因此,我们可以通过规定线程获取资源的顺序来预防死锁。修改示例代码如下:

public class DeadlockExample {
    public static void main(String[] args) {
        Resource resource1 = new Resource("Resource1");
        Resource resource2 = new Resource("Resource2");

        Thread t1 = new Thread(() -> {
            synchronized (resource1) {
                System.out.println("Thread 1 acquired resource 1.");
                synchronized (resource2) {
                    System.out.println("Thread 1 acquired resource 2.");
                }
            }
        });

        Thread t2 = new Thread(() -> {
            synchronized (resource1) {
                System.out.println("Thread 2 acquired resource 1.");
                synchronized (resource2) {
                    System.out.println("Thread 2 acquired resource 2.");
                }
            }
        });

        t1.start();
        t2.start();
    }
}

通过对资源的获取顺序进行规定,确保不会出现互相等待对方所需的资源的情况,从而避免了死锁的发生。

  1. 死锁检测和恢复:

除了预防死锁,还可以通过死锁检测和恢复来解决死锁问题。Java提供了ThreadMXBean接口用于监测和管理线程的状态。以下是一个示例代码:

import java.lang.management.ManagementFactory;
import java.lang.management.ThreadMXBean;

public class DeadlockExample {
    public static void main(String[] args) {
        Resource resource1 = new Resource("Resource1");
        Resource resource2 = new Resource("Resource2");

        Thread t1 = new Thread(() -> {
            synchronized (resource1) {
                System.out.println("Thread 1 acquired resource 1.");

                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                synchronized (resource2) {
                    System.out.println("Thread 1 acquired resource 2.");
                }
            }
        });

        Thread t2 = new Thread(() -> {
            synchronized (resource2) {
                System.out.println("Thread 2 acquired resource 2.");

                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                synchronized (resource1) {
                    System.out.println("Thread 2 acquired resource 1.");
                }
            }
        });

        t1.start();
        t2.start();

        ThreadMXBean threadMxBean = ManagementFactory.getThreadMXBean();
        long[] deadlockedThreadIds = threadMxBean.findDeadlockedThreads();

        if (deadlockedThreadIds != null) {
            ThreadInfo[] threadInfos = threadMxBean.getThreadInfo(deadlockedThreadIds);
            for (ThreadInfo threadInfo : threadInfos) {
                System.out.println(threadInfo.getThreadName() + " is deadlocked.");
                // 恢复死锁线程的执行,或者进行其他操作
            }
        }
    }
}

在上面的示例代码中,我们通过ThreadMXBeanfindDeadlockedThreads

Une impasse se produit lorsque ces deux threads s'attendent pour libérer les ressources requises. Bien sûr, il ne s’agit que d’un exemple simple, et les scénarios réels peuvent inclure davantage de ressources et de threads.

2. Résoudre le problème de l'impasse :

Prévenir l'impasse :

  1. Pour éviter l'impasse, vous devez d'abord comprendre la cause de l'impasse. Dans l'exemple de code ci-dessus, le blocage est dû au fait que les threads acquièrent des ressources dans un ordre incohérent. Par conséquent, nous pouvons éviter les blocages en spécifiant l’ordre dans lequel les threads acquièrent les ressources. Modifiez l'exemple de code comme suit :
  2. rrreee
  3. En stipulant l'ordre dans lequel les ressources sont obtenues, il garantit que l'autre n'attend pas les ressources requises par l'autre partie, évitant ainsi l'apparition d'une impasse.
    1. Détection et récupération des blocages : 🎜🎜🎜En plus de prévenir les blocages, les problèmes de blocage peuvent également être résolus grâce à la détection et à la récupération des blocages. Java fournit l'interface ThreadMXBean pour surveiller et gérer l'état des threads. Voici un exemple de code : 🎜rrreee🎜Dans l'exemple de code ci-dessus, nous trouvons le thread où le blocage s'est produit via la méthode findDeadlockedThreads de ThreadMXBean et le gérons en conséquence. Vous pouvez reprendre l'exécution du thread bloqué ou effectuer d'autres opérations. 🎜🎜Conclusion : 🎜🎜Le blocage est l'un des problèmes courants dans la programmation simultanée multithread. S'il n'est pas résolu, il peut entraîner le blocage du programme ou l'impossibilité de poursuivre son exécution. Cet article présente deux méthodes pour résoudre le problème de blocage, à savoir la prévention des blocages et la détection et la récupération des blocages. Bien entendu, ce ne sont là que quelques solutions de base, et des stratégies plus complexes peuvent être nécessaires pour résoudre le problème de blocage dans les applications réelles. Les développeurs doivent veiller à éviter les blocages lors de l'écriture de programmes simultanés multithread et les gérer de manière appropriée pour garantir la stabilité et la fiabilité du programme. 🎜🎜Matériel de référence : 🎜🎜🎜[Programmation simultanée Java : compréhension approfondie de la synchronisation](https://www.jianshu.com/p/6d293a1a412c)🎜🎜[Analyse et solution du problème de blocage des threads Java](https : //blog .csdn.net/coslay/article/details/78387673)🎜🎜

    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