DeadLock et ses causes - 1

« Salut Amigo ! »

"Aujourd'hui, je vais vous dire ce qu'est une impasse."

"Hé, tu m'as déjà parlé de quelque chose comme ça."

"Oui, je l'ai fait. Mais aujourd'hui, nous allons examiner le sujet plus en détail."

"Dans le cas le plus simple, le blocage implique deux threads et deux objets mutex. Un verrou mutuel se produit lorsque :"

A) Chaque thread doit acquérir les deux mutex.

B)  Le premier thread a acquis le premier mutex et attend que le second soit libéré.

C)  Le deuxième thread a acquis le deuxième mutex et attend que le premier soit libéré.

"Voici quelques exemples:

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

"Supposons qu'un thread appelle la méthode getFriends , acquiert le mutex de cet objet, puis acquiert le mutex de l'objet amis ."

"Pendant ce temps, un deuxième thread appelle la méthode addFriend , acquiert le mutex de l'objet amis , puis acquiert le mutex de cet objet (lors d'un appel à getFriendsCount )."

"Au début, tout ira bien, mais comme le stipule la loi de Murphy : tout ce qui peut mal tourner ira mal. Une situation se produira inévitablement où le premier thread n'aura le temps d'acquérir qu'un seul mutex, et le second thread acquerra le second mutex à ce moment précis. Ils resteront suspendus comme ça, attendant toujours que l'autre thread libère le mutex.

"J'ai décidé de citer un autre exemple simple que j'ai trouvé dans un livre :"

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

"Il y a un jeu où deux chevaliers se battent. Un chevalier tue l'autre. Ce comportement se reflète dans la méthode de mise à mort . Deux objets chevalier lui sont passés.

"Tout d'abord, nous protégeons les deux objets afin que personne d'autre ne puisse les modifier."

"Le deuxième chevalier meurt (HP = 0)"

"Le premier chevalier gagne 100 XP."

"Tout semble bien, mais il peut y avoir des situations où le deuxième chevalier attaque le premier en même temps. Cette méthode est également appelée pour le deuxième chevalier, mais les objets du chevalier sont passés dans un ordre différent."

« Vous voulez dire que nous n'avons même pas besoin de plusieurs méthodes pour obtenir une impasse ?

"D'accord. Parfois, il suffit d'une seule méthode simple pour que les threads et l'ensemble du programme se bloquent."

« Ouais, je suppose que ce phénomène se produit plus souvent que je ne le pensais. Merci, Ellie.