Search code examples
javawaitnotify

Java Wait/Notify not working


So I have been working on a simple wait/notify example in Java and for some reason I have not been able to get it to run properly. If anyone is able to see what might be the issue It would be very appreciated!

public class ThreadDemonstration
{
private String str = null;

Thread stringCreator = new Thread(new Runnable()
{
    public void run()
    {           
        synchronized(this)
        {               
            str = "I have text";
            notify();            
        }
    }
});

private Thread stringUser = new Thread(new Runnable()
{
    public void run()
    {
        synchronized(this)
        {
            if(str == null)
            {                   
                try {
                    System.out.println("str is null, I need help from stringCreator");
                    wait();
                    System.out.println(str);
                }
                catch (InterruptedException e) 
                {
                    e.printStackTrace();
                }
            }

        }
    }
});

public static void main (String [] args)
{
    ThreadDemonstration td = new ThreadDemonstration();
    td.stringUser.start();
    td.stringCreator.start();
}

}

My current output is: str is null, I need help from stringCreator

So for some reason the thread stringCreator does not wake up the stringUser or am I missing something else entirely?

Thank you!


Solution

  • Your blocks are synchronized over different objects. They should be synchronized over a common object, for example the monitor object below:

    public class ThreadDemonstration
    {
    private String str = null;
        private final Object monitor = new Object();
    
    Thread stringCreator = new Thread(new Runnable()
    {
        public void run()
        {           
            synchronized(monitor)
            {               
                str = "I have text";
                monitor.notify();            
            }
        }
    });
    
    private Thread stringUser = new Thread(new Runnable()
    {
        public void run()
        {
            synchronized(monitor)
            {
                while(str == null) //changed from if to while. This allows you to wait again if the thread gets woken up by something other than the appropriate notify.
                {                   
                    try {
                        System.out.println("str is null, I need help from stringCreator");
                        monitor.wait();
                        //removed print statement from here
                    }
                    catch (InterruptedException e) 
                    {
                        e.printStackTrace();
                    }
                }
                System.out.println(str); //added print statement here. str is guaranteed to not be null here.
            }
        }
    });
    

    In order to avoid creating a separate object for synchronization, you can use synchronized(ThreadDemonstration.this) or synchronized(ThreadDemonstration.class) for example.