Heim > Java > javaLernprogramm > Hauptteil

Wie kann man Deadlocks in der gleichzeitigen Java-Programmierung verhindern und damit umgehen?

PHPz
Freigeben: 2024-05-08 14:48:02
Original
832 Leute haben es durchsucht

Deadlock ist ein häufiges Problem bei der gleichzeitigen Programmierung und kann durch Maßnahmen verhindert oder behoben werden: Deadlock verhindern: - Sperren in der richtigen Reihenfolge erwerben - zyklisches Warten vermeiden - Timeout-Mechanismus verwenden - Deadlocks mithilfe nicht blockierender Datenstrukturen behandeln: - Deadlock-Erkennung - Deadlock-Wiederherstellung – Vorgang wiederholen

Java 并发编程中的死锁如何预防和处理?

Deadlock-Verhinderung und -Behandlung in der gleichzeitigen Java-Programmierung

Deadlock ist ein häufiges Problem, das bei der gleichzeitigen Programmierung auftreten kann und dazu führt, dass mehrere Threads aufeinander warten System zum Stillstand bringen. In Java können Deadlocks durch geeignete Maßnahmen verhindert oder behandelt werden.

Deadlocks verhindern

  • Sperren in dieser Reihenfolge erwerben: Definieren Sie eine Reihenfolge für den Zugriff auf die Ressourcen und stellen Sie sicher, dass alle Threads Sperren in dieser Reihenfolge erwerben. Wenn beispielsweise Thread A auf die Ressourcen X und Y zugreifen muss und Thread B auf die Ressourcen Y und Z zugreifen muss, sollten alle Threads zuerst die Sperre für X und dann die Sperre für Y erwerben.
  • Vermeiden Sie zirkuläre Wartezeiten: Stellen Sie sicher, dass ein Thread nicht versucht, die Sperre erneut zu erlangen, während er darauf wartet, dass ein anderer Thread die Sperre aufhebt. Wenn Thread A beispielsweise darauf wartet, dass Thread B die Sperre für Ressource X aufhebt, sollte Thread A nicht erneut versuchen, die Sperre für X zu erlangen.
  • Timeout-Mechanismus verwenden: Legen Sie ein Timeout fest, damit der Thread die Sperre erhält. Wenn der Thread die Sperre nicht innerhalb der angegebenen Zeit erhalten kann, sollte er die Sperre aufgeben und eine andere Methode ausprobieren.
  • Verwenden Sie nicht blockierende Datenstrukturen: Die Verwendung nicht blockierender Datenstrukturen wie ConcurrentHashMap kann die Möglichkeit eines Deadlocks verringern. Diese Datenstrukturen ermöglichen Threads den gleichzeitigen Zugriff auf Daten, ohne Sperren zu verwenden.

Umgang mit Deadlocks

Wenn vorbeugende Maßnahmen Deadlocks nicht verhindern können, können Sie Deadlocks folgendermaßen behandeln:

  • Deadlock-Erkennung: Verwenden Sie Sperrüberwachungstools oder benutzerdefinierte Erkennungsmechanismen, um Deadlocks zu identifizieren.
  • Deadlock-Wiederherstellung: Sobald ein Deadlock erkannt wird, kann das System wiederhergestellt werden, indem die gesperrten Ressourcen freigegeben oder einer der am Deadlock beteiligten Threads unterbrochen werden.
  • Deadlock erneut versuchen: Nachdem Sie die Ressource freigegeben oder unterbrochen haben, können Sie die Ausführung erneut versuchen, wodurch verhindert werden kann, dass es erneut zu einem Deadlock kommt.

Praktischer Fall

Betrachten Sie den folgenden Java-Codeausschnitt:

public class DeadlockExample {

    private final Object lock1 = new Object();
    private final Object lock2 = new Object();

    public void method1() {
        synchronized (lock1) {
            System.out.println("Thread " + Thread.currentThread().getName() + " acquired lock1");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (lock2) {
                System.out.println("Thread " + Thread.currentThread().getName() + " acquired lock2");
            }
        }
    }

    public void method2() {
        synchronized (lock2) {
            System.out.println("Thread " + Thread.currentThread().getName() + " acquired lock2");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (lock1) {
                System.out.println("Thread " + Thread.currentThread().getName() + " acquired lock1");
            }
        }
    }

    public static void main(String[] args) {
        DeadlockExample deadlockExample = new DeadlockExample();

        Thread thread1 = new Thread(deadlockExample::method1);
        Thread thread2 = new Thread(deadlockExample::method2);

        thread1.start();
        thread2.start();
    }
}
Nach dem Login kopieren

In diesem Beispiel werden zwei Threads (Thread1 und Thread2) mit Lock1 bzw. Lock2 synchronisiert. Da beide Threads Sperren in umgekehrter Reihenfolge erwerben, warten sie darauf, dass der andere die Sperre aufhebt, was zu einem Deadlock führt.

Um einen Deadlock zu verhindern, können wir den Code ändern, um Sperren in der folgenden Reihenfolge zu erhalten:

public class DeadlockExample {

    private final Object lock1 = new Object();
    private final Object lock2 = new Object();

    public void method1() {
        synchronized (lock1) {
            System.out.println("Thread " + Thread.currentThread().getName() + " acquired lock1");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (lock2) {
                System.out.println("Thread " + Thread.currentThread().getName() + " acquired lock2");
            }
        }
    }

    public void method2() {
        synchronized (lock2) {
            System.out.println("Thread " + Thread.currentThread().getName() + " acquired lock2");
            synchronized (lock1) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("Thread " + Thread.currentThread().getName() + " acquired lock1");
            }
        }
    }

    public static void main(String[] args) {
        DeadlockExample deadlockExample = new DeadlockExample();

        Thread thread1 = new Thread(deadlockExample::method1);
        Thread thread2 = new Thread(deadlockExample::method2);

        thread1.start();
        thread2.start();
    }
}
Nach dem Login kopieren

Durch die Änderung des Codes stellen wir sicher, dass Thread1 und Thread2 Sperren immer in der gleichen Reihenfolge erwerben (Sperre1, dann Sperre2), und verhindern so einen Deadlock.

Das obige ist der detaillierte Inhalt vonWie kann man Deadlocks in der gleichzeitigen Java-Programmierung verhindern und damit umgehen?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage