0

如何根据复杂模型的一部分是否产生正确的标志,在控制器中进行操作?如何将一个复杂的Model类与一个Controller类进行同步?

控制器类正在播放Midi序列的队列,同时保留通过用户按钮按动态更新的模型类的实例。 Midi队列结束后,控制器需要与模型同步以检查用户是否已经创建了一定数量的条目,然后再继续更新界面并移至应用程序的下一部分。除了用户按钮的ArrayList外,Model还代表了很多其他数据,因此挑战在于如何最佳划分同步部分。

现在,我想的模式是类似于下面的东西,它不因为控制器和模型之间嵌套类访问工作:

//Controller 
... 
Thread entriesCoordination = new Thread(new Model.InnerClass); 
entriesCoordination.start(); 

Thread t = new Thread (this); 
t.run(); 

... 
//in runnable nested class in controller 
private Model.InncerClass c = new Model.InnerClass(); 
public void run() { 
    synchronized(c) { 
     while (!c.hasFinishedEntries()){ 
      try{ 
       c.wait(); 
      } catch (InterruptedException ignore{} 
      } 
     } 
    } 
    //Midiqueue completed and Entries finished 
} 
//in Model 
//in runnable nested class in Model 
public synchronized boolean hasFinishedEntries() { 
    return fIsFinishedWithEntries; 
} 

public void run() { 
    while(true) { 
     try{ 
      synchronized(this) { 
       try{ 
        if(entriesArray.size() == max_size) { 
         fIsFinishedWithEntries = true; 
         notifyAll(); 
        } else {...} 
       } 
      } 
     } 
    } 
} 

而且,这似乎是浪费的,因为它基本上意味着我需要创建一个线程,并且在用户可以进行这些按钮选择的整个持续时间内并行运行Model的内部类,而不是在知道Midi队列时只轮询Model结束了。

什么是synchronizeController类的Model类中的一个标志到synchronize的设计模式,而不必为了处理同步而在模型中创建内部类。

回答

0

我想在这里做的事情是使用AtomicBoolean并定义在每个线程对象的方法来获取和设置布尔。

Model.InnerClass更改为添加AtomicBoolean并将getter更改为不同步。

private final AtomicBoolean fIsFinishedWithEntries = new AtomicBoolean(); 
public boolean hasFinishedEntries() { 
    return fIsFinishedWithEntries.get(); 
} 

在run方法中,需要将完成的布尔值设置为true。

public void run() { 
    while(true) { 
      if (entriesArray.size() == max_size) { 
       synchronized (this) { 
        fIsFinishedWithEntries.set(true); 
        notifyAll(); 
       } 
      } else {...} 
     } 
    } 
} 

你需要给它休息,false如果一个地方你正在做不止一次这样了。

现在,我想的模式是类似于下面的东西,它不因为控制器和模型之间嵌套类访问工作:

您需要先创建Model.InnerClass实例和注入到您的控制器线程中。使得hasFinishedEntries()是静态的是丑陋所以不是在你的控制器,你会打电话:

private Model.InnerClass innerClass; 
public ControllerThread(Model.InnerClass innerClass) { 
    this.innerClass = innerClass; 
} 
... 
public void run() { 
    synchronized (innerClass) { 
     while (!innerClass.hasFinishedEntries()){ 
      innerClass.wait(); 
     } 
    } 
} 

如何访问是否条目,而不会对整个模型类同步完成?

只要你想看看队列是否结束,你显然可以轮询hasFinishedEntries()。我不确定没有线程的更好方法。有没有办法设置一个UI事件,每隔一段时间检查一次条件?

+0

谢谢格雷。我更新了这个问题,在控制器中创建'Model.InnerClass',就像你建议的@Gray一样。我并不认为我真的需要一个原子获取,设置,放在布尔值上,因为控制器始终得到并且模型总是放入,这不会为来自交错放入的东西留下任何线程干扰的空间。总的来说,你是否认为通过嵌套的“runnable”内部类来实现这一点,是将同步展现给模型的某个部分,同时将其与整个Model类完全分离的方式? – Datum0101 2012-03-15 20:54:02

+0

您正在寻找一种方法来查看是否已完成_without_ synchronizing。如果你总是等待,那么我会同意AtomicBoolean不是必需的。 – Gray 2012-03-15 20:58:48

+0

嵌套的'Runnable'内部类很好。由于内部对象的可见性,您在内部类上同步时遇到问题。有很多方法可以解决这个问题。一种方法是在调用内部类的外部类中放置一个'hasFinished()'方法。你也可以在其他类可以看到的外部类中的内部类上锁定一个“static final Object lockObject = new Object();'。但外部方法调用更清洁。 – Gray 2012-03-15 21:02:16

相关问题