Pergunta

I made this sample to test wait/notify functionalities:

public class WaitingTest implements Runnable {

    Thread b = new Thread(this,"query");
    int total=0;

    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(10);
                }catch(InterruptedException e){
                    e.printStackTrace();
                }
                System.out.println("Total is: " + total);
            }

    }   
    @Override
    public void run(){

     synchronized(b){
           for(int i=0; i<1000000000 ; i++){
                total += i;
            }

        }
    }
}

The problem is, my output should be zero since Im notifying the wait after 10ms and my thread takes longer than this to execute its work. So, my output should be zero, instead its coming another value. What am I missing?

EDIT:

public class WaitingTest implements Runnable {

        Thread b = new Thread(this,"query");
        int total=0;

        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){
             b.notify();
               for(long i=0; i<100000 ; i++){
                    total += i;
                }

            }
        }
    }
Foi útil?

Solução

The javadoc for wait() states

This method causes the current thread (call it T) to place itself in the wait set for this object and then to relinquish any and all synchronization claims on this object

So when you do

b.wait(10);

the current thread releases the synchronized it has on b and your other thread can therefore acquire it in the run() method coming from

b.start();

The total starts increasing. When 10ms is up, the main thread reacquires the lock on b (assuming the run() completes) and prints out the total. Note that your total will most likely overflow.

Outras dicas

You get overflow (you cannot sum up these 1000000000 non-negative ints and store the
result in an int). Define total as long. Also call b.notify() or b.notifyAll()
after your loop in the run method is done.
Also, change wait(10) to just wait(), this will make the printing thread wait for
the calculating thread as much as needed (and not just for 10 milliseconds).
This is the proper way of doing this test.

Regarding the thread syncing part I suggest you read something e.g. these old articles.

http://www.javaworld.com/article/2074217/java-concurrency/java-101--understanding-java-threads--part-1--introducing-threads-and-runnables.html

http://www.javaworld.com/article/2074318/java-concurrency/java-101--understanding-java-threads--part-2--thread-synchronization.html

http://www.javaworld.com/article/2071214/java-concurrency/java-101--understanding-java-threads--part-3--thread-scheduling-and-wait-notify.html

http://www.javaworld.com/article/2074481/java-concurrency/java-101--understanding-java-threads--part-4---thread-groups--volatility--and-threa.html

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top