简体   繁体   English

Java等待/通知不起作用

[英]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. 因此,我一直在研究Java中的简单等待/通知示例,由于某种原因,我无法使其正常运行。 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 我当前的输出是: str为null,我需要stringCreator的帮助

So for some reason the thread stringCreator does not wake up the stringUser or am I missing something else entirely? 因此,由于某种原因,线程stringCreator不会唤醒stringUser,或者我是否还完全缺少其他东西?

Thank you! 谢谢!

Your blocks are synchronized over different objects. 您的块在不同的对象上synchronized They should be synchronized over a common object, for example the monitor object below: 它们应通过公共对象(例如下面的monitor对象)进行synchronized

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. 为了避免创建单独的对象进行同步,例如,可以使用synchronized(ThreadDemonstration.this)synchronized(ThreadDemonstration.class)

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);

    //----
});

You need to use the wait and notify of the same instance in order for it to work. 您需要使用waitnotify同一实例,以使其起作用。 Since you create two different objects (2 instances of Runnable ) it will not work. 由于您创建了两个不同的对象(2个Runnable实例),因此它将不起作用。 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. 您也可以为此使用一个“虚拟对象”( Object lock = new Object )。

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();
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM