2017-01-05 9 views
0
public class DeadlockDemo2 { 

    public static Object Lock1 = new Object(); 
    public static Object Lock2 = new Object(); 

    public static void main(String[] args) { 
     // TODO Auto-generated method stub 
     ThreadDemo1 demo1 = new ThreadDemo1(); 
     ThreadDemo2 demo2 = new ThreadDemo2(); 
     demo1.start(); 
     demo2.start(); 
    } 

    private static class ThreadDemo1 extends Thread { 
     public void run() { 
      synchronized (Lock1) { 
       System.out.println("Thread 1: Holding lock 1..."); 

       try { 
        Thread.sleep(10); 
       } catch (InterruptedException e) { 
       } 
       System.out.println("Thread 1: Waiting for lock 2..."); 

       synchronized (Lock2) { 
        System.out.println("Thread 1: Holding lock 1 & 2..."); 
       } 
      } 
     } 
    } 

    private static class ThreadDemo2 extends Thread { 
     public void run() { 
      synchronized (Lock2) { 
       System.out.println("Thread 2: Holding lock 2..."); 

       try { 
        Thread.sleep(10); 
       } catch (InterruptedException e) { 
       } 
       System.out.println("Thread 2: Waiting for lock 1..."); 

       synchronized (Lock1) { 
        System.out.println("Thread 2: Holding lock 1 & 2..."); 
       } 
      } 
     } 
    } 
} 

В приведенной выше программе обе нитки спадают в течение 10 миллисекунд. Таким образом, как только время истекает, demo1 может получить блокировку lock2 и demo2 на lock1. Но этого не происходит. Они заходят в тупик.Поведение режима сна в синхронизированном блоке

Может ли кто-нибудь объяснить причину?

Заранее спасибо.

ответ

0

Мы проигнорируем здесь проблемы с дизайном и предположим, что вы просто пытаетесь понять резьбу с примером игрушек.

Проблема заключается в том, что вы заблокировали область обзора. Давайте перечислить порядок операций здесь:

В ThreadDemo1:

  1. Приобретать Lock1
  2. Сон
  3. Приобретать Lock2
  4. Free Lock2
  5. Free Lock1

Аналогично, в ThreadDemo2:

  1. Acquire Lock2
  2. Сон
  3. Приобретать Lock1
  4. Free Lock1
  5. Free Lock2

Как видно из порядка операций здесь , оба из y наши классы ThreadDemo пытаются приобрести другой замок, прежде чем освободить их первоначальную блокировку. Это в основном гарантирует тупиковую ситуацию, поскольку они будут застрять навсегда, ожидая, что другой выпустит свой первоначальный замок.

То, что вы на самом деле хотели случиться было это в ThreadDemo1:

  1. Acquire Lock1
  2. Сон
  3. Free Lock1
  4. Приобретать Lock2
  5. Free Lock2

И это в ThreadDemo2:

  1. Приобретать Lock2
  2. Сон
  3. Free Lock2
  4. Приобретать Lock1
  5. Free Lock1

Чтобы сделать это, просто изменить:

private static class ThreadDemo1 extends Thread { 
    public void run() { 
     synchronized (Lock1) { 
      System.out.println("Thread 1: Holding lock 1..."); 

      try { 
       Thread.sleep(10); 
      } catch (InterruptedException e) { 
      } 
      System.out.println("Thread 1: Waiting for lock 2..."); 

      synchronized (Lock2) { 
       System.out.println("Thread 1: Holding lock 1 & 2..."); 
      } 
     } // <----- We're going to move this bracket 
    } 
} 

Для этого:

private static class ThreadDemo1 extends Thread { 
    public void run() { 
     synchronized (Lock1) { 
      System.out.println("Thread 1: Holding lock 1..."); 

      try { 
       Thread.sleep(10); 
      } catch (InterruptedException e) { 
      } 
     } // <----- We moved it here 
     System.out.println("Thread 1: Waiting for lock 2..."); 

     synchronized (Lock2) { 
      System.out.println("Thread 1: Holding lock 1 & 2..."); 
     } 
    } 
} 

И сделать то же самое изменение в вашем ThreadDemo2 классе

+0

Спасибо за объяснение. Это действительно полезно. У меня просто одно сомнение, если нет сна(), это работает нормально. Даже в этом случае это не будет заторможено? –

+0

Без сна теоретически возможно, что «ThreadDemo1» завершит всю свою работу до того, как «ThreadDemo2» даже начнет выполнение благодаря времени раскрутки нити и времени планирования. Это не значит, что вы удалили тупик, просто вам не хватает его. Если вместо этого вы замените сон какой-то более длинной единицей работы, вам нужно снова зайти в тупик. – aruisdante

+0

ok. Благодарю. Я наткнулся на еще одну программу, которую я не могу вставить здесь. Http://www.journaldev.com/1058/deadlock-in-java-example. Если программа запущена, она не заканчивается. Если я изменил продолжительность сна, чтобы сказать 1000 мс от 30000 (который указан) в методе work(), все потоки выполняются один за другим. Я не понимаю, как сон влияет на результат здесь? Можете ли вы пролить свет на него? –

 Смежные вопросы

  • Нет связанных вопросов^_^