Как создать поток для сложного класса Model, чтобы обеспечить синхронизацию с классом Controller? - PullRequest
0 голосов
/ 15 марта 2012

Как я могу действовать в контроллере, основываясь на том, что только одна часть сложной модели выдает правильный флаг?

Класс контроллера воспроизводит очередь последовательностей Midi, удерживая экземпляр класса модели, который динамически обновляется с помощью нажатия пользовательских кнопок. После завершения очереди Midi контроллер должен синхронизироваться с моделью, чтобы проверить, что пользователь сделал определенное количество записей, прежде чем приступить к обновлению интерфейса и переходу к следующей части приложения. Модель представляет довольно много других данных в дополнение к ArrayList нажатий пользовательских кнопок, поэтому задача состоит в том, как лучше разделить синхронизирующую часть.

Прямо сейчас, шаблон, который я пробую, похож на следующий, который не работает из-за вложенного доступа к классу между контроллером и моделью:

//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 параллельно всю продолжительность времени, в течение которого пользователь может делать эти выборки кнопок, а не то, что будет просто опросить Model, когда я узнаю, что очередь Midi закончилась.

Что такое шаблон проектирования для synchronize одного флага в классе Model из класса Controller без необходимости создания внутреннего класса в модели только для обработки синхронизации.

1 Ответ

0 голосов
/ 16 марта 2012

Я думаю, что здесь нужно использовать AtomicBoolean и определить методы для каждого из ваших объектов потока, чтобы получить и установить логическое значение.

Model.InnerClass будет изменено, чтобы добавитьAtomicBoolean и изменить геттер, чтобы не синхронизироваться.

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

В методе run необходимо что-то установить для конечного логического значения как истинное.

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();
        }
    }
}

Как я могу получить доступ к завершению записей без синхронизации для всего класса Model?

Очевидно, вы можете просто опрашивать hasFinishedEntries() всякий раз, когда хотите узнать, закончилась ли очередь.Я не уверен в лучшем способе сделать это без потока.Есть ли способ настроить событие пользовательского интерфейса, которое периодически проверяет состояние?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...