„Здрасти, Амиго!“
„Днес ще ви кажа Howво е безизходица.“
— Хей, ти вече ми каза за нещо подобно.
"Да, направих. Но днес ще разгледаме темата по-подробно."
"В най-простия случай блокирането включва две нишки и два mutex обекта. Взаимно заключване възниква, когато:"
A) Всяка нишка трябва да придобие и двата мутекса.
B) Първата нишка е придобила първия мютекс и чака вторият да бъде освободен.
C) Втората нишка е придобила втория мютекс и чака първият да бъде освободен.
"Ето няколко примера:
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 ();
}
}
}
„Да предположим, че една нишка извиква метода getFriends , придобива мутекса на този обект и след това придобива мутекса на обекта приятели .“
„Междувременно втора нишка извиква метода addFriend , придобива мутекса на обекта friends и след това придобива мутекса на този обект (по време на извикване на getFriendsCount ).“
„Първоначално всичко ще бъде наред, но Howто гласи законът на Мърфи: всичко, което може да се обърка, ще се обърка. Неизбежно ще възникне ситуация, при която първата нишка ще има време да придобие само един мютекс, а втората нишка ще придобие втория mutex точно в този момент. Те ще висят така, вечно чакайки другата нишка да освободи mutex."
„Реших да цитирам друг прост пример, който намерих в една книга:“
class KnightUtil
{
public static void kill(Knight knight1, Knight knight2)
{
synchronized(knight1)
{
synchronized(knight2)
{
knight2.live = 0;
knight1.experience += 100;
}
}
}
}
„Има игра, в която двама рицари се бият помежду си. Единият рицар убива другия. Това поведение е отразено в метода на убийство . Към него се подават два предмета на рицаря.
„Първо, защитаваме и двата обекта, така че никой друг да не може да ги промени.“
„Вторият рицар умира (HP = 0)“
„Първият рицар печели 100 XP.“
„Всичко изглежда добре, но може да има ситуации, при които вторият рицар атакува първия по едно и също време. Този метод се извиква и за втория рицар, но обектите на рицаря се предават в различен ред.“
„Искате да кажете, че дори не се нуждаем от множество методи, за да стигнем до безизходица?“
"Точно така. Понякога е необходим само един прост метод, за да предизвика нишките и цялата програма да висят."
„Да, предполагам, че това явление се случва по-често, отколкото си мислех. Благодаря, Ели.“
GO TO FULL VERSION