2015-11-06 2 views
0

Подумав о решении, я не знаю, почему этот код работает неправильно.Почему notifyAll() не работает?

Если я исполняю mediaPlayer.start(), то поток входит в петлю и wait(), но затем, когда mediaPlayer звонки OnCompletionListener, notifyAll() не просыпаются от wait() и петли в wait() состоянии навсегда ...

(Предположив, что ' Музыка Thread»правильно начал в начале класса, и то же самое с MediaPlayer объекта)

private synchronized void set() 
{ 
    while(mediaPlayer.isPlaying()) 
{ 
    try {  
     wait(); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
} 
    //DO SOMETHING (THE PROBLEM IS THAT NEVER REACHES THIS CODE) 
} 




private synchronized void reproductor() 
{ 
    mediaPlayer.start(); 
    mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { 
     @Override 
     public synchronized void onCompletion(MediaPlayer mediaPlayer) { 
      notifyAll(); //because mediaPlayer.isPlaying() changes 

     } 
    }); 
} 



private class Music implements Runnable 
{ 
    @Override 
    public void run() { 
     try { 
      reproductor(); 
      while(true) { 
       set(); 
       Thread.sleep(500); 
      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 
} 

с другой стороны, если я использую противоположное утверждение в цикле он работает правильно (!mediaPlayer.isPlaying()), почему?

+0

Похож на классическое «потерянное уведомление»: http://stackoverflow.com/questions/5999100/is-there-a-block-until-condition-becomes-true-function-in-java/26218153#26218153 –

ответ

0

Вы не уведомлены о том же объекте, которого вы ожидаете. Вы уведомляете объект-слушатель, который является экземпляром анонимного класса, реализующего интерфейс прослушивателя. Вы должны квалифицировать notifyAll() как XXX.this.notifyAll(), где XXX - это то же самое класса, в котором используются методы set() и reproductor().

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