简体   繁体   中英

Why notifyAll() doesn't work?

After been thinking about a solution, i don't know why this code doesn't works properly.

If I execute mediaPlayer.start() , the thread enters on loop and wait() , but then, when mediaPlayer calls OnCompletionListener , notifyAll() doesn't wake from wait() , and loops in wait() state forever...

(Supposing that 'Music Thread' is properly started at the start of the class, and the same with MediaPlayer object)

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

On the other hand, if i use contrary statement in loop it works properly ( !mediaPlayer.isPlaying() ), why?

You aren't notifying the same object you're waiting on. You're notifying the listener object, which is an instance of an anonymous class implementing the listener interface. You need to qualify notifyAll() as XXX.this.notifyAll() , where XXX is the same of the class enclosing the set() and reproductor() methods.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM