2013-09-26 2 views
1

Возможно ли в любом случае получить «ожидание навсегда» в ThreadA. Я имею в виду, что уведомление выполняется быстрее, чем b.sync.wait();поток ждет навсегда для случая уведомления

class ThreadA { 
     public static void main(String [] args) { 
     ThreadB b = new ThreadB(); 

     b.start(); 

     synchronized(b.sync) 
     { 
      try 
      { 
       System.out.println("Waiting for b to complete..."); 
       b.sync.wait(); 
       System.out.println("waiting done"); 
      } catch (InterruptedException e) {}   
     } 
     } 
} 

class ThreadB extends Thread { 
    int total=0; 
    Integer sync = new Integer(1); 
    public void run() { 


     synchronized(sync) 
     { 
      sync.notify(); 
     } 
    } 
} 

ответ

2

Да, это возможно. Как только вы вызываете b.start(), планировщик может выбрать запуск потока B, и он сразу же получит блокировку и уведомление о вызове, когда поток A не ждет блокировки. В этой ситуации угроза A позже получит блокировку и продолжит ждать навсегда.

Если вам необходимо детерминированное поведение, вы должны позвонить b.start() только после того, как вы начали ждать уведомления.

+0

Это означает, что в моей ситуации, в случае, если мне нужно избегать спать Forewer я должен позвонить b.start() в некоторой ThreadC, ожидая в ThreadA. – vico

+0

@ user1501700 Правильно. В общем случае использование 'wait()' и 'notify()' сегодня обескуражено, так как у нас есть пакет 'java.util.concurrent'. Например, 'CountDownLatch' будет делать то, что вам нужно (' await() 'в A,' countDown() 'in B) без синхронизации. –

0

Нет гарантии на исполнение ваших ниток. Возможно (и, насколько я помню, как потоки, как правило, работают на Java), уведомление произойдет до вызова wait().

Вы почти никогда не можете предположить, что что-то произойдет раньше.

Список действий, которые создают происходит, прежде чем отношения, см: Java Memory Visibility или главы 17 The Java™ Language Specification