How can I proceed in a controller based on whether just one part of a complex model has produced the correct flag?
A controller class is playing a queue of Midi sequences while holding onto an instance of a model class that is dynamically updated via user button presses. After the Midi queue ends, the controller needs to synchronize with the model to check that the user has made a certain number of entries before proceeding to update the interface and move to the next part of the application. The Model represents quite a lot of other data in addition to the ArrayList of user button presses, so the challenge is how to best compartmentalize the synchronization part.
Right now, the pattern I’m trying is something like the following, which doesn’t work because of nested class access between the controller and the 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 {...}
}
}
}
}
}
Furthermore, this seems wasteful because it basically means that I need to create a thread and run the inner class of the Model in parallel the entire duration of the time that the user can make these button selections, rather than something that would just poll the Model when I know that the Midi queue has ended.
What’s the design pattern to synchronize to one flag in a Model class from a Controller class without having to make a inner class in the model just to handle the synchronization.
I think the right thing to do here is to use an
AtomicBooleanand define methods on each of your thread objects to get and set the boolean.The
Model.InnerClasswould be changed to add theAtomicBooleanand to change the getter to not be synchronized.In the run method it something needs to set the finished boolean to be true.
You’ll need to rest it to
falsesomewhere if you are doing this more than once.You need to first create your
Model.InnerClassinstance and inject that into your controller thread. Making thehasFinishedEntries()be static is ugly so instead in your controller you’d call:You can obviously just poll the
hasFinishedEntries()whenever you want to see if the queue has ended. I’m not sure of a better way to do this without a thread. Is there some way to setup a UI event which checks for a condition every so often?