Java Wait/Notify not working

↘锁芯ラ 提交于 2019-12-11 09:08:15

问题


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!


回答1:


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.




回答2:


Try this :

private Thread stringUser = new Thread(new Runnable() {
    //-----

    System.out.println("str is null, I need help from stringCreator");
    notify();
    wait(100);
    System.out.println(str);

    //----
});



回答3:


You need to use the wait and notify of the same instance in order for it to work. Since you create two different objects (2 instances of Runnable) it will not work. I've written a simple example using two different classes using the main class' instance for the intrinsic lock. You could also us a 'dummy object' (Object lock = new Object) for this.

public class ThreadDemonstration {

    private static String text;

    public ThreadDemonstration(){
        Thread user = new Thread(new StringUser(this));
        Thread creator = new Thread(new StringCreator(this));
        user.start();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        creator.start();
    }

    public class StringCreator implements Runnable{

        private Object lock;

        StringCreator(Object lock){
            this.lock = lock;
        }

        @Override
        public void run() {
            synchronized(lock){
                text = "Yeeeehaaaaa";
                lock.notify();
            }

        }

    }

    public class StringUser implements Runnable{

        private Object lock;

        StringUser(Object lock){
            this.lock = lock;
        }

        @Override
        public void run() {

            synchronized(lock){

                if((text == null)){
                    System.out.println("I need help!");
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println(text);
            }

        }

    }

    public static void main(String[] args){
        new ThreadDemonstration();
    }

}


来源:https://stackoverflow.com/questions/19524594/java-wait-notify-not-working

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!