DeadLock și cauzele sale - 1

"Bună, Amigo!"

„Astăzi am să vă spun ce este blocajul”.

— Hei, mi-ai spus deja despre așa ceva.

"Da, am făcut-o. Dar astăzi vom analiza subiectul mai detaliat."

„În cel mai simplu caz, blocarea implică două fire și două obiecte mutex. O blocare reciprocă are loc atunci când:”

A) Fiecare fir trebuie să achiziționeze ambele mutexuri.

B)  Primul fir a dobândit primul mutex și așteaptă ca al doilea să fie eliberat.

C)  Al doilea fir a dobândit al doilea mutex și așteaptă ca primul să fie eliberat.

"Aici sunt cateva exemple:

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

„Să presupunem că un fir apelează metoda getFriends , dobândește mutex-ul acestui obiect și apoi achiziționează mutex-ul obiectului friends .”

„Între timp, un al doilea thread apelează metoda addFriend , achiziționează mutex-ul obiectului prieteni și apoi achiziționează mutex-ul acestui obiect (în timpul unui apel la getFriendsCount ).”

„La început, totul va fi bine, dar așa cum spune Legea lui Murphy: orice poate merge prost va merge prost. Va apărea inevitabil o situație în care primul fir va avea timp doar să dobândească un mutex, iar al doilea fir va dobândi al doilea. mutex chiar în acel moment. Se vor agăța așa, așteaptă pentru totdeauna ca celălalt fir să elibereze mutexul."

„Am decis să citez un alt exemplu simplu pe care l-am găsit într-o carte:”

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

„Există un joc în care doi cavaleri se luptă între ei. Un cavaler îl ucide pe celălalt. Acest comportament se reflectă în metoda uciderii . Două obiecte cavalere îi sunt transmise.

„În primul rând, protejăm ambele obiecte, astfel încât nimeni altcineva să nu le poată schimba”.

„Al doilea cavaler moare (HP = 0)”

„Primul cavaler câștigă 100 XP”.

"Totul pare în regulă, dar pot exista situații în care al doilea cavaler îl atacă pe primul în același timp. Această metodă este numită și pentru al doilea cavaler, dar obiectele cavalerului sunt trecute într-o ordine diferită."

„Vrei să spui că nici măcar nu avem nevoie de mai multe metode pentru a ajunge în impas?”

„Corect. Uneori este nevoie de o singură metodă simplă pentru a bloca firele și întregul program”.

— Da, cred că acest fenomen are loc mai des decât credeam. Mulțumesc, Ellie.