Nicholas TJ
Nicholas TJ

Reputation: 1659

Android Java Notify does not trigger wait

I'm trying to understand this concurrent programming with threads and I don't seem to get this wait() and notify()

I suspect that it has something to do with one of my thread waiting forever and the notify is already called. But I don't know how to solve this. I read through others posts on stackoverflow, but could not understand it well.

Here is my code and it would be helpful if someone could pinpoint me to the right direction.

package com.example.thread_android;

import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;

public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Log.d("Stage", "onCreate");

    Runnable AthreadJob = new ARunnable();
    Runnable BthreadJob = new BRunnable();
    Thread myThreadOne = new Thread(AthreadJob);
    Thread myThreadTwo = new Thread(BthreadJob);
    myThreadOne.start();
    myThreadTwo.start();

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.activity_main, menu);
    return true;
}
}

class ARunnable implements Runnable{
@Override
public void run(){
    Log.d("Runnable", "A Inside Run - WAIT");
    try{
        synchronized(this){wait();}
    } catch (InterruptedException e) {}
    //Log.d("Runnable", "A Inside Run - CONTINUE");
}
}

class BRunnable implements Runnable{
@Override
public void run(){
    Log.d("Runnable", "B Inside Run");
    synchronized (this) {notify();}
}
}

Upvotes: 0

Views: 983

Answers (2)

Stephen C
Stephen C

Reputation: 718946

JB Nizet's advice is sound. Don't start learning multi-threading using wait/notify. You should start with the higher signalling mechanisms; e.g. Semaphores, Latches, Futures, and so on.

However, the reason your code that is blocked in wait() in ARunnable.run is not seeing the notify() in BRunnable.run is that the wait and notify are being performed on different objects. If you want one "runnable" to signal the other, they need a shared object, and they both need to synchronize on that object and call wait() and notify on it.

Upvotes: 2

sanbhat
sanbhat

Reputation: 17622

In the code

class ARunnable implements Runnable{
@Override
public void run(){
    Log.d("Runnable", "A Inside Run - WAIT");
    try{
        synchronized(this){wait();}
    } catch (InterruptedException e) {}
    //Log.d("Runnable", "A Inside Run - CONTINUE");
}
}

this means the running instance of ARunnable. This instance is actually the thread monitor (An object thread locks/unlocks to execute the synchronized block), and you have asked the current thread to wait();.

To make the waiting thread wake-up and run again, some other thread, holding the same monitor (i,e the same instance of ARunnable) should invoke notify() or notifyAll();. Something like below

class ARunnable implements Runnable{
    boolean ready = false;
    //setter for ready..
    @Override
    public void run(){
        Log.d("Runnable", "A Inside Run - WAIT");
        try{
            synchronized(this){
                if(!ready) {
                      wait();
                }
                else {
                     notifyAll(); // Now the thread which was waiting earlier, will wake-up and start resuming the execution.
                }
            }
        } catch (InterruptedException e) {}
        //Log.d("Runnable", "A Inside Run - CONTINUE");
    }
    }

Upvotes: 1

Related Questions