Активная замена в ожидании - правильный ли мой подход по дизайну?
Я избавляюсь от ожидания:
public void run() {
while(!running) {} //active waiting
//some action after running is true
}
Мой код:
class MyThread implements Runnable {
protected boolean running = false;
public Object lock = new Object();
@Override
public void run() {
while(!running) {
synchronized(lock) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}//end lock
}
//main job which will be done when the flag running is true
}//end run
public void managerStateChanged (Manager m) {
if(m.getState() == 1) {
this.running = true;
synchronized(lock) {
lock.notify();
}
}
}
}
class Manager {
protected MyThread listener = null;
protected int state = 0;
public int getState() { return state; }
public void registerListener(MyThread l) {
listener = l;
}
public void managerStateChanged() {
if(listener != null) {
listener.managerStateChanged(this);
}
}
}
Редактировать:
1) Для всех - будьте осторожны при использовании этого, и wait(), и notify() должны быть обернуты в синхронизированный блок, иначе это вызовет IlegalMonitorException, когда у вас это есть в вашем коде и вы все еще получаете этот поиск исключений снова, вероятно, вызывается другой уведомить куда-нибудь еще без этого синхронизированного блока. Спасибо за комментарии.
2) Я изменил вопрос, так как мой код был в порядке, но sh** происходит, и я забыл удалить что-то где-то. Это работает нормально. Вопрос в правильности моей реализации?
Есть некоторые моменты, в которых я не совсем уверен:
- Я избавляюсь от активного ожидания через ожидание и оповещаю о каком-либо объекте
- Когда оценка программы доходит до цикла while, поток спит на объекте, поток делает все, и активное ожидание заменяется пассивным ожиданием, так что это намного лучше для CPU.
- Когда в Manager происходит изменение состояния и вызывается соответствующий ему метод managerStateChanged(), он вызывает тот же метод в спящем потоке MyThread, который проверит, находится ли его состояние в ожидании, если нет, то поток все еще спит, если да, флаг выполнения изменяется, и поток просыпается, условие цикла while больше не является циклом, и мы выпрыгиваем из пассивного ожидания, и поток продолжает использовать свой полезный код после цикла while
- Есть еще одна вещь, которая должна быть рассмотрена, и ее ложное пробуждение, что поток может быть разбужен перед уведомлением, я надеюсь, что это не должно быть проблемой здесь, потому что, если он проснулся до того, как уведомить пассивное, пока условие цикла все еще не выполнено поэтому он снова засыпает, и ложное пробуждение не должно быть проблемой.
Мои догадки об этом правы? Код понятен? Разве я не пропустил что-то, что нужно лечить лучше? Надеюсь нет. Спасибо за ответы.