DeadLock e suas causas - 1

"Olá, amigo!"

"Hoje vou te contar o que é impasse."

"Ei, você já me contou sobre algo assim."

"Sim, eu fiz. Mas hoje vamos considerar o assunto com mais detalhes."

"No caso mais simples, o impasse envolve dois threads e dois objetos mutex. Um bloqueio mútuo ocorre quando:"

A) Cada thread precisa adquirir ambos os mutexes.

B)  A primeira thread adquiriu o primeiro mutex e está aguardando a liberação do segundo.

C)  A segunda thread adquiriu o segundo mutex e está aguardando a liberação da primeira.

"Aqui estão alguns exemplos:

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

"Suponha que um thread chame o método getFriends , adquira o mutex deste objeto e, em seguida, adquira o mutex do objeto friends ."

"Enquanto isso, um segundo thread chama o método addFriend , adquire o mutex do objeto friends e, em seguida, adquire o mutex deste objeto (durante uma chamada para getFriendsCount )."

"No início, tudo ficará bem, mas como afirma a Lei de Murphy: tudo o que pode dar errado vai dar errado. Surgirá inevitavelmente uma situação em que o primeiro thread só terá tempo de adquirir um mutex e o segundo thread adquirirá o segundo mutex naquele exato momento. Eles ficarão pendurados assim, sempre esperando que a outra thread libere o mutex."

"Resolvi citar outro exemplo simples que encontrei em um livro:"

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

"Há um jogo em que dois cavaleiros estão lutando entre si. Um cavaleiro mata o outro. Esse comportamento é refletido no método de matar . Dois objetos de cavaleiro são passados ​​para ele.

"Primeiro, protegemos os dois objetos para que ninguém mais possa alterá-los."

"O segundo cavaleiro morre (HP = 0)"

"O primeiro cavaleiro ganha 100 XP."

"Tudo parece bem, mas pode haver situações em que o segundo cavaleiro ataca o primeiro ao mesmo tempo. Este método também é chamado para o segundo cavaleiro, mas os objetos do cavaleiro são passados ​​em uma ordem diferente."

"Você quer dizer que não precisamos de vários métodos para obter um impasse?"

"Certo. Às vezes, é necessário apenas um método simples para fazer com que os threads e todo o programa sejam interrompidos."

"Sim, acho que esse fenômeno ocorre com mais frequência do que eu pensava. Obrigado, Ellie."