0

I have a Thread Object - ThreadB which add numbers 1 - 100. I create 2 instances of it - b & c.

Start the 2 threads(different instances) and run it.

Result:

    Waiting for b to complete...
    Total is: 4950
    Waiting for c to complete...

Why does my second instance does not complete...

Java code:

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

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

            System.out.println("Total is: " + b.total);
        }

        synchronized(c){
            try{
                System.out.println("Waiting for c to complete...");
                c.wait();
            }catch(InterruptedException e){
                e.printStackTrace();
            }

            System.out.println("Total is: " + c.total);
        }
    }
}

class ThreadB extends Thread{
    int total;
    @Override
    public void run(){
        synchronized(this){
            for(int i=0; i<100 ; i++){
                total += i;
            }
            notify();
        }
    }
}

3 Answers 3

2

Because your second ThreadB finishes while you're in the block synchronized on the first ThreadB. You then wait on your second ThreadB, but the notify() has already happened so you'll wait there forever.

Note that this isn't guaranteed, and your program will probably work sometimes.

Put some print statements inside your ThreadB class to test this theory.

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks, got it..I have one more question..What will happen if b.start() completes before it reaches synchronized(b) instruction?
What happened when you put together a little example program to test it out?
I tried it and b.start() does not complete before the synchrnozied(b) instruction is started but Im not sure if its right or wrong. The threads are totally dependant on the JVM, so it may work differently in other machines.
Yep, exactly. You can either introduce a false wait time in one of the threads to test it out, or you can trace through what would happen by hand.
FWIW, That mistake has a name, "lost notification."
1

If you just wish to wait for both threads to complete you should use the Thread join method, which is specifically designed for this.

It also makes use of wait and notify (or rather notifyAll) underneath the hood.

Your code will be much cleaner too:

System.out.println("Waiting for b to complete...");
b.join();
System.out.println("b completed.");

System.out.println("Waiting for c to complete...");
c.join();
System.out.println("c completed.");

System.out.println("b's total is " + b.total");
System.out.println("c's total is " + c.total");

Comments

0

This is not the right way to approach the problem. You are trying to serialize two independent threads, which is pointless.

If your only purpose is to give the user some feedback, you make each thread inform the user that it terminated its job before quitting:

    class ThreadB extends Thread{
    String name;
    int total;

    public ThreadB(String name){
        this.name = name;
    }

    @Override
    public void run(){
        System.out.println("Waiting for "+name+" to complete...");
        for(int i=0; i<100 ; i++){
            total += i;
        }
        System.out.println(name+" completed. Total is "+total);

    }
}

public class ThreadA {
    public static void main(String[] args){
        ThreadB b = new ThreadB("b");
        ThreadB c = new ThreadB("c");
        b.start();
        c.start();
    }
}

Otherwise, if you need to do something after all threads have finished, you synchronize on a shared object, not on a thread.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.