Тупиковые ситуации и синхронизированные методы

Я нашел один из кодов на Stack Overflow, и я подумал, что он очень похож на то, с чем я столкнулся, но я все еще не понимаю, почему это может зайти в тупик. Пример был взят из Обнаружение взаимоблокировок в Java :

Class A
{
  synchronized void methodA(B b)
  {
    b.last();
  }

  synchronized void last()
  {
    System.out.println(“ Inside A.last()”);
  }
}

Class B
{
  synchronized void methodB(A a)
  {
    a.last();
  }

  synchronized void last()
  {
    System.out.println(“ Inside B.last()”);
  }
}

Class Deadlock implements Runnable 
{
  A a = new A(); 
  B b = new B();

  // Constructor
  Deadlock()
  {
    Thread t = new Thread(this); 
    t.start();
    a.methodA(b);
  }

  public void run()
  {
    b.methodB(a);
  }

  public static void main(String args[] )
  {
    new Deadlock();
  }
}

В этом случае, когда вызывается конструктор Deadlock (), он запускается как поток. Когда это происходит, вызывается метод run (). Он вызовет b.methodB (a), который затем вызовет a.last (), чтобы просто распечатать оператор. В то же время a.methodA (b) вызовет b.last (). Нет перекрестных зависимостей ни от одного объекта, и они также не выполняют метод одновременно. Даже если это так, ключевое слово synchronized поставило бы их в очередь, не так ли? Но почему это тоже могло иногда заходить в тупик?Это происходит не всегда, но иногда он заходит в тупик, что довольно непредсказуемо. Что заставляет это зайти в тупик и обходные пути?

5
задан Erik 21 June 2018 в 19:17
поделиться