2011-12-01 123 views
1

所以这是我的代码,调查我的应用程序的模型中的更改。什么是建议替代使用while循环轮询

Thread refreshThread = new Thread(new Runnable() { 

     public void run() { 

      while(true) 
      {      
       if(TasksManager.isDirty()) 
       { 
        TasksManager.refreshTasks(true); 
        panel.repaint(); 
       } 
      } 
     } 
    }); 
    refreshThread.start(); 

现在它是一个巨大的CPU猪。 下面是发生了什么的细节。

  1. TaskManager意识到已添加新内容。
  2. TaskManager将自己标记为脏。
  3. 当我的刷新线程发现它很脏时,它立即在模型和显示面板上执行刷新。
  4. 在RefreshTasks()结束时,模型再次被标记为干净。

我不希望TaskManager开始刷新,因为它没有对查看面板进行任何引用。

我有一个想法是使用condition.await()。当TaskManager被标记为脏时,TaskManager可以发出信号。但是我看到锁和条件齐头并进。在函数的开头不使用锁而使用条件可以吗?

+1

你在做什么本质上是一样的:打电话给你最好的朋友。问他是否想给你打电话。如果答案是否定的,挂断电话。等一下。重复。 – Laf

+0

我相信这是投票的隐喻定义。 – psykeron

回答

3

您可以使用wait()notifyAll()以避免CPU使用率很高:

private final Object dirtyLock = new Object(); 

Thread refreshThread = new Thread(new Runnable() { 
    public void run() { 
     while(true){ 
      synchronized(dirtyLock){ 
       dirtyLock.wait(); // Send this thread to sleep until dirtyLock is unlocked      
      } 
      TasksManager.refreshTasks(true); 
      panel.repaint(); 
     } 
    }); 
refreshThread.start(); 

// When your TaskManager becomes dirty, do the following 
public void changeToDirty(){ 
    TaskManager.setDirty(true); 
    synchronized(dirtyLock){ 
      dirtyLock.notifyAll(); 
      // this will release the refresh thread which will repaint and then go to sleep 
    } 
} 
+0

这听起来像是一个很好的快速解决方案。就设计而言,哪一个会是更好的选择?使用监听器还是使用等待线程?我认为使用监听器是一个更好的设计解决方案。尽管现在我只是试图让我的代码工作,等待更好地为我的目的服务。 – psykeron

+0

关于进一步思考,这是方法本质上再次是一个监听器,我的静态TasksManager类可以将其保存在侦听器数组中以进行通知。 – psykeron

+0

试过这种方法,它不会工作,因为线程不拥有该对象。它会抛出一个IllegalMonitorState异常。 – psykeron

4

为什么你不使用监听器?

如果您有一个名为ContentChangedListener的简单的TasksManager子类,然后,您可以在侦听器中声明panel.repaint()声明,该侦听器可以从感兴趣的任何人向TasksManager注册。许多听众可以根据需要进行注册。

代替将TasksManager标记为脏的代码,将其替换为循环以通知所有听众更改。

该解决方案的优点是不需要其他线程或循环。

+0

我的代码是以这样一种方式构造的,即查看面板在主类中初始化。 TasksManager是静态的。我可以看到如何添加一个监听器来简化事情。 (我的代码设计非常混乱:/)。所以这个听众必须持有对该小组的参考,对吗? AAAAAH ......我明白了,我明白了。 – psykeron

+0

我喜欢这个主意,但是我使用了GETAH提到的方法。 – psykeron