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

相關問題