void transfer(Account from,Account to,int money){ from.setAmount(from.getAmount()-money); to.setAmount(to.getAmount()+money); }
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
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 DeadlocksDas 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!