2014-02-19 97 views
1

我一直在努力理解wait(),notify()和synchronized方法的用法。我有这个例子,它不起作用。其他一些对象调用dataHasChanged(),它将实例变量datachanged的值更改为true。然后,使用notifyAll(),等待的线程将检查值datachanged。到现在为止还挺好。但是:当在while(!datachanged)中检查时,datachanged的值是false。所以,我认为,datachanged = true不知道怎么注册我的Refresher-Object。我究竟做错了什么?通知等待线程更改变量

public synchronized void dataHasChanged(){ 
    datachanged = true; 
    notifyAll(); 
} 

class Refresher extends SwingWorker<Void, Void>{ 

    public synchronized void refresh(){ 
     while(!datachanged){ 
      try { 
       wait(); 
      } catch (InterruptedException ex) { 
       Exceptions.printStackTrace(ex); 
      } 
     } 
     setRights(); 
     datachanged = false;    
    } 

    @Override 
    protected Void doInBackground() throws Exception { 
     refresh(); 
     return null; 
    } 

    @Override 
    protected void done() { 
     refresher = new Refresher(); 
     refresher.execute(); 
    } 


} 
+0

请注意''this'上调用'notifyAll()'。在你的'dataHasChanged()'中,这是一个与'refresh()'不同的对象。另外,考虑做'datachanged'' volatile'。 –

+0

你有多少个线程正在运行(使用函数refresh()),你是如何定义“datachanged”的? –

+0

@Andreas M.每个外部类的实例只有一个Refresher-Thread正在运行。 datachanged是私有的volatile布尔值。 –

回答

2

wait(), notify(), notifyAll()并同步对每个对象进行操作。在你的情况下,refresh()在Refresh实例上等待并且notifyAll()通知所有在你的外部类的实例上等待的对象。为此,wait()和notifyAll()必须在同一个对象上调用(所以synchronized())。

以下内容将对外部类的实例执行所有操作。

public void refresh(){ 
    synchronized(WhateverYourOuterClass.this){ 
     while(!datachanged){ 
      try { 
       WhateverYourOuterClass.this.wait(); 
      } catch (InterruptedException ex) { 
       Exceptions.printStackTrace(ex); 
      } 
     } 
     setRights(); 
     datachanged = false;    
    } 
} 
+0

就是这样。感谢为我解决这个问题 –