简体   繁体   中英

Does wait always need notify to work?

Till now I was aware that wait always need notify to work properly.But when tried the below code I am confused a bit about the working of wait and notify. I created three threads t1,t2,t3 and passed the runnable T1,T2 and T3 respectively.According to me when i started the three threads only t1 should print and t2 and t3 should go to waiting state and keeps on waiting as no one is notifying.

But the o/p is unpredictable for me.Can someone please expalin me a bit.Below are my classes.

package com.vikash.Threading;

class T1 implements Runnable {

    private State state;

    public T1(State state) {
        this.state=state;
    }

    @Override
    public void run() {

        synchronized (state) {
            while(state.getState()!=1) {
                try {
                    state.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            synchronized (state) {
                System.out.println(Thread.currentThread().getName());
                state.setState(2);
            }
        }
    }
}

class T2 implements Runnable {

    private State state;

    public T2(State state) {
        this.state=state;
    }

    @Override
    public void run() {

        synchronized (state) {
            while(state.getState()!=2) {
                try {
                    state.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            synchronized (state) {
                System.out.println(Thread.currentThread().getName());
                state.setState(3);
            }
        }
    }
}

class T3 implements Runnable {

    private State state;

    public T3(State state) {
        this.state=state;
    }

    @Override
    public void run() {

        synchronized (state) {
            while(state.getState()!=3) {
                try {
                    state.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            synchronized (state) {
                System.out.println(Thread.currentThread().getName());
                state.setState(1);
            }
        }
    }
}

public class Sequence {

    public static void main(String[] args) {

        State state=new State();
        Thread t1=new Thread(new T1(state),"First");
        Thread t2=new Thread(new T2(state),"Second");
        Thread t3=new Thread(new T3(state),"Third");
        t1.start();
        t2.start();
        t3.start();
    }
}



package com.vikash.Threading;

public class State {

    private int state=1;

    public int getState() {
        return state;
    }

    public void setState(int state) {
        this.state = state;
    }
}

As per comment I am modifying my question.The o/p sometimes I am getting First second and it does not terminate and sometimes First Second Third and terminate.

Your expectation is incorrect, it is possible for all your threads to print and end as your program is currently written (but this depends on random chance)

It depends on which thread grabs the monitor on state first using the synchronized block that they all have.

Consider this flow:

  1. T1 enters the synchronized (state) block first. T2 and T3 are waiting to enter their synchronized (state) blocks.
  2. T1 doesn't wait as state.getState() == 1 , so instead
  3. T1 prints the thread name and assigns 2 to state.state
  4. T1 exits the synchronized block
  5. Either T2 or T3 enter their synchronized (state) block, assume that it is T2 (which one enters first is undefined behaviour in Java, and likely this is random)
  6. So T2 doesn't wait as state.getState() == 2
  7. T2 prints the thread name and assigns 3 to state.state
  8. T2 exits the synchronized block
  9. T3 enters the synchronized block, doesn't wait, and prints the thread name
  10. Program done.

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