Pergunta

I made this sample to understand how Wait-Notify works:

public class WaitingTest implements Runnable {

    Thread b = new Thread();
    int total;

    public static void main(String[] args){
        WaitingTest w = new WaitingTest();
    }

    public WaitingTest(){
        b.start();
            synchronized(b){
                try{
                    System.out.println("Waiting for b to complete...");
                    b.wait();
                }catch(InterruptedException e){
                    e.printStackTrace();
                }
                System.out.println("Total is: " + total);
            }
    }

    @Override
    public void run(){
        synchronized(b){
            for(int i=0; i<100 ; i++){
                total += i;
                System.out.println(total);
            }
            b.notify();
        }
    }
}

But I'm stuck here for hours and I can't understand why it's not quite working. My output should be more than 0, but its always zero...I was wondering if its becuase of the usage of different threads, but Im not really sure..What am I missing?

Foi útil?

Solução

I think you have some serious holes in your understanding. You've declared a Thread

Thread b = new Thread();

and started it in the constructor

b.start();

That Thread will start and die right away since it has no Runnable attached to it.

It just so happens that when a Thread dies, it calls notify() on itself and since you are synchronized on that same Thread object, your wait()ing thread will be awoken. You also have a race here. If the Thread ends before the main thread reaches the wait(), you will be deadlocked.

Also, there is no reason for run() to be called, which is why total remains 0.


Any object can be synchronized on, it doesn't have to be a Thread. And since Thread has that weird behavior of notify()ing itself, you probably shouldn't use it.

You should go through both the Thread tutorials and the synchronization tutorials.

Outras dicas

Apart from the problem with how you have arranged your threads, you have a incorrect use of wait()/notify()

notify() is stateless. If no thread is waiting, nothing will be notified. If you wait() later it will not be notified.

wait() can wake spuriously. Just because wait() woke doesn't mean anything notified it.

This means you need to associate wait/notify with state (in fact it's rather pointless without it)

For example.

 // to notify
 synchronized(lock) {
     signalled = true;
     lock.notify();
 }

 // to wait
 synchronized(lock) {
     while(!signalled)
          lock.wait();
 }
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top