DeadLock en de oorzaken ervan - 1

"Hallo Amigo!"

"Vandaag ga ik je vertellen wat impasse is."

"Hé, zoiets heb je me al verteld."

'Ja, dat heb ik gedaan. Maar vandaag gaan we dieper op het onderwerp in.'

"In het eenvoudigste geval gaat het bij deadlock om twee threads en twee mutex-objecten. Een wederzijdse vergrendeling treedt op wanneer:"

A) Elke thread moet beide mutexen verwerven.

B)  De eerste thread heeft de eerste mutex verkregen en wacht op de release van de tweede.

C)  De tweede thread heeft de tweede mutex verkregen en wacht op de release van de eerste.

"Hier zijn enkele voorbeelden:

Voorbeeld
 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 ();
  }
 }
}

"Stel dat een thread de getFriends- methode aanroept, de mutex van dit object verwerft en vervolgens de mutex van het vrienden- object verkrijgt."

"Ondertussen roept een tweede thread de addFriend- methode aan, verwerft de mutex van het vrienden- object en verwerft vervolgens de mutex van dit object (tijdens een oproep om getFriendsCount )."

"In het begin komt alles goed, maar zoals de wet van Murphy stelt: alles wat fout kan gaan, zal fout gaan. Er zal onvermijdelijk een situatie ontstaan ​​waarin de eerste thread slechts tijd heeft om één mutex te verwerven, en de tweede thread de tweede mutex op dat moment. Ze zullen zo blijven hangen, voor altijd wachtend op de andere thread om de mutex vrij te geven.'

"Ik heb besloten om nog een eenvoudig voorbeeld te citeren dat ik in een boek vond:"

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

"Er is een spel waarbij twee ridders met elkaar vechten. De ene ridder doodt de andere. Dit gedrag wordt weerspiegeld in de kill- methode. Er worden twee ridderobjecten aan doorgegeven.

"Ten eerste beschermen we beide objecten zodat niemand anders ze kan veranderen."

"De tweede ridder sterft (HP = 0)"

"De eerste ridder krijgt 100 XP."

"Alles lijkt in orde, maar er kunnen situaties zijn waarin de tweede ridder tegelijkertijd de eerste aanvalt. Deze methode wordt ook gebruikt voor de tweede ridder, maar de ridderobjecten worden in een andere volgorde doorgegeven."

'Bedoel je dat we niet eens meerdere methoden nodig hebben om een ​​impasse te krijgen?'

"Juist. Soms is er maar één simpele methode nodig om threads, en het hele programma, vast te laten lopen."

"Ja, ik denk dat dit fenomeen vaker voorkomt dan ik dacht. Bedankt, Ellie."