Heim  >  Artikel  >  Java  >  [JAVA] Das Auftreten und die Lösung eines Deadlocks

[JAVA] Das Auftreten und die Lösung eines Deadlocks

php是最好的语言
php是最好的语言Original
2018-08-06 13:44:333174Durchsuche

                                       Situation

void transfer(Account from,Account to,int money){
    from.setAmount(from.getAmount()-money);
    to.setAmount(to.getAmount()+money);
}

Unter Single Thread ist dieser Code definitiv kein Problem, aber unter Multithreading gibt es ein Problem

Jetzt sperren , der gesperrte Code ist wie folgt

void transfer(Account from,Account to,int money){
    synchronized(from){
        synchronized(to){
            from.setAmount(from.getAmount()-money);
            to.setAmount(to.getAmount()+money);
        }
    }
}

Synchronisiert, das heißt Objektsperre, die erste synchronisierte Sperre sperrt das Von-Objekt und die zweite Synchronisierte sperrt das Ziel-Objekt.

Im Fall von Multithreading kann nur ein Thread unter mehreren Threads gleichzeitig die Objektsperre erhalten und das Codesegment in der Objektsperre bedienen

Aber nach dem Hinzufügen der Objektsperre , es kann zu einem Stillstand kommen!

transfer(a,b,100) und transfer(b,a,100) werden gleichzeitig ausgeführt, das heißt, während a Geld an b überweist, überweist b auch Geld an a

【1】a Geld an b überweisen, Thread, kann der Überweisungsvorgang durchgeführt werden

Operation [2] Die Objektsperre a wird dringend benötigt, bevor der Überweisungsvorgang durchgeführt werden kann

Beide Threads warten darauf, dass andere Threads in der Gruppe die Sperre aufheben, und es kommt zu einem Deadlock!

2. Um den Stillstand zu lösen

In welchen Aspekten sollten wir beginnen?

【1】Warten auf gegenseitigen Ausschluss brechen

Im Allgemeinen müssen wir zur Sicherheit des Programms das Objekt sperren, sodass diese Bedingung im Allgemeinen nicht gebrochen werden kann

【2 】Brechen Sie den Halt und warten Sie, das heißt, halten Sie und warten Sie

, um alle Ressourcen auf einmal abzurufen. Im Beispielcode werden die beiden Ressourcen von und bis nicht gleichzeitig abgerufen, sondern auf einmal verteilter Weise.

Methode 1: Fügen Sie eine kurze Zeitüberschreitung hinzu, sobald der Versuch, to abzurufen, abläuft, heben Sie sofort die ursprünglich gehaltene From-Sperre auf und versuchen Sie es nach einer gewissen Zeit erneut.

Rufen Sie den From ab und zu Schlössern. Dies ist die empfohlene Methode

Methode 2: Fügen Sie diesem Code eine globale Sperre hinzu, um sicherzustellen, dass „von“ und „bis“ gleichzeitig abgerufen werden. Nach Abschluss des Übertragungsvorgangs wird die globale Sperre aufgehoben. Es ist relativ sicher, aber es gibt viele Bankkonten und die Verwendung dieser Methode führt zwangsläufig zu einem erheblichen Leistungsabfall

[3] Durchbrechen Sie die Warteschleife

Besorgen Sie sich Ressourcen In der Reihenfolge werden Übertragungsvorgänge entsprechend der Größe der Konto-ID ausgeführt. Konten mit kleineren IDs führen zuerst Übertragungsvorgänge aus, und Konten mit größeren IDs führen

Übertragungsvorgänge später aus. Aber im wirklichen Leben haben manche Dinge keine ID, also keine Ordnung. Zu diesem Zeitpunkt ist es notwendig, ihnen Ordnung zu verschaffen.

【4】Brechen Sie das unwiderrufliche Warten

Fügen Sie als letzten Ausweg eine Zeitüberschreitung hinzu. Der Übertragungsvorgang des Benutzers ist fehlgeschlagen und die Benutzererfahrung ist nicht gut

Persönlich empfohlene Lösung:

Opfern Sie die kurze Wartezeit des Benutzers und verwenden Sie Methode 1 in [2]

Verwandte Artikel:

Das Konzept und die Lösung von Deadlocks in Java

Das Konzept des Deadlocks und die Bedingungen des Deadlocks

Das obige ist der detaillierte Inhalt von[JAVA] Das Auftreten und die Lösung eines Deadlocks. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
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