2013-10-22 92 views
1

所以我一直在研究一个简单的等待/通知的例子在Java中,由于某些原因,我一直无法让它正常运行。如果有人能够看到可能是什么问题,将非常感谢!Java等待/通知不起作用

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

}

我的电流输出为: str是空的,我需要从stringCreator

帮助,所以出于某种原因线程stringCreator没有醒stringUser还是我失去了完全是另一回事?

谢谢!

+1

您认为'new'的Runnable(){...}'值是多少? – Pshemo

+0

我现在明白了,谢谢:) –

回答

4

您的区块为​​,覆盖不同的物件。他们应该是​​过公共对象,例如下面的monitor对象:

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

为了避免创建同步单独的对象,可以使用例如synchronized(ThreadDemonstration.this)synchronized(ThreadDemonstration.class)

+0

谢谢,我已经更新了相应的例子。 – Piovezan

+0

大获成功!谢谢你Piovezan! :-) –

+0

仍不确定这是否完整。如果'StringCreator'首先获得锁,它将设置'str',然后'notify()'。当'StringUser'获得锁时'str'不为null,所以它不会'wait()'(这很好),但它也不会打印'str'。 – Cruncher

1

试试这个:

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

    //---- 
}); 
+0

记得将代码添加到代码块以获得更好的格式化 –

+0

在此代码中还有1个大括号和3个大括号。 – Cruncher

0

您需要使用相同的实例的waitnotify以便为它工作。由于您创建了两个不同的对象(Runnable的两个实例),它将无法工作。我已经写了一个简单的例子,它使用两个不同的类,使用主类的内部锁的实例。你也可以为我们设置一个“虚拟对象”(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(); 
    } 

}