DeadLock und seine Ursachen - 1

„Hallo, Amigo!“

„Heute werde ich Ihnen sagen, was Deadlock ist.“

„Hey, du hast mir schon von so etwas erzählt.“

„Ja, das habe ich. Aber heute werden wir das Thema genauer betrachten.“

„Im einfachsten Fall umfasst ein Deadlock zwei Threads und zwei Mutex-Objekte. Eine gegenseitige Sperre tritt auf, wenn:“

A) Jeder Thread muss beide Mutexe erwerben.

B)  Der erste Thread hat den ersten Mutex erhalten und wartet auf die Freigabe des zweiten.

C)  Der zweite Thread hat den zweiten Mutex erhalten und wartet auf die Freigabe des ersten.

"Hier sind einige Beispiele:

Beispiel
public class Student
{
 private ArrayList friends = new ArrayList();

 public synchronized ArrayList getFriends()
 {
  synchronized(friends)
  {
   return new ArrayList(friends);
  }
 }

 public synchronized int getFriendsCount()
 {
  return friends.size();
 }

 public int addFriend(Student student)
 {
  synchronized(friends)
  {
   friends.add(student)
   return getFriendsCount ();
  }
 }
}

„Angenommen, ein Thread ruft die getFriends- Methode auf, ruft den Mutex dieses Objekts ab und ruft dann den Mutex des Friends- Objekts ab.“

„In der Zwischenzeit ruft ein zweiter Thread die Methode addFriend auf , ruft den Mutex des Friends- Objekts ab und ruft dann den Mutex dieses Objekts ab (während eines Aufrufs von getFriendsCount ).“

„Zuerst wird alles gut sein, aber wie Murphys Gesetz besagt: Alles, was schief gehen kann, wird schief gehen. Es wird unweigerlich eine Situation entstehen, in der der erste Thread nur Zeit hat, einen Mutex zu erwerben, und der zweite Thread wird den zweiten erwerben Mutex in diesem Moment. Sie bleiben so hängen und warten ewig darauf, dass der andere Thread den Mutex freigibt.

„Ich habe beschlossen, ein weiteres einfaches Beispiel zu zitieren, das ich in einem Buch gefunden habe:“

Beispiel
class KnightUtil
{
 public static void kill(Knight knight1, Knight knight2)
 {
  synchronized(knight1)
  {
   synchronized(knight2)
   {
    knight2.live = 0;
    knight1.experience += 100;
   }
  }
 }
}

„Es gibt ein Spiel, in dem zwei Ritter gegeneinander kämpfen. Ein Ritter tötet den anderen. Dieses Verhalten spiegelt sich in der Kill- Methode wider. Zwei Ritterobjekte werden an ihn übergeben.

„Zuerst schützen wir beide Objekte, damit niemand sonst sie ändern kann.“

„Der zweite Ritter stirbt (HP = 0)“

„Der erste Ritter erhält 100 XP.“

„Alles scheint in Ordnung zu sein, aber es kann Situationen geben, in denen der zweite Ritter gleichzeitig den ersten angreift. Diese Methode wird auch für den zweiten Ritter aufgerufen, aber die Ritterobjekte werden in einer anderen Reihenfolge übergeben.“

„Sie meinen, wir brauchen nicht einmal mehrere Methoden, um einen Deadlock zu bekommen?“

„Richtig. Manchmal braucht es nur eine einfache Methode, um Threads und das gesamte Programm zum Hängen zu bringen.“

„Ja, ich schätze, dieses Phänomen kommt häufiger vor, als ich dachte. Danke, Ellie.“