новичок в многопоточности - как использовать wait () и notify () в Java? - PullRequest
2 голосов
/ 19 июля 2010

Я пытаюсь написать программу с 2 классами, контроллером и классом, который выполняет много вычислений. Контроллер создает пару экземпляров другого класса, а затем говорит им всем начать свои вычисления (параллельно). Каждый из них возвращается после завершения, и контроллер возобновляет работу, а затем, через некоторое время, контроллер передает им новые данные и заставляет их снова выполнить расчет.
В идеале я мог бы вызывать start () с параметрами, но это невозможно, поэтому контроллер вызывает метод в калькуляторе, который хранит данные в глобальном, а затем запускает поток вычислений и возвращает, который работает до Я пытаюсь запустить поток снова, и он говорит мне, что поток мертв. Поэтому я пытаюсь сделать запуск бесконечным циклом, который просто ждет, пока не получит уведомление, выполняет вычисления, сохраняет результаты в глобальном, чтобы контроллер мог получить их позже, а затем возобновляет ожидание. Так что-то вроде:

//in controller:
Calculator calc=new Calculator();
calc.runCalculations(data);
while(calc.isCalculating()){
    //do nothing
}
System.out.println("results: "+calc.getAnswer());
calc.runCalculations(data2);

//in calculator:
public runCalculations(Data data){
    globalData=data;
    this.notify();
}
public void run(){
    while(true){
        synchronized(this){
            wait();
        }
        calculating=true;
        globalData=calculate(globalData);
        calculating=false;
    }
}

1 Ответ

4 голосов
/ 19 июля 2010

Вам необходимо получить монитор на this, прежде чем звонить notify(). Кроме того, когда вы вызываете wait(), вы должны делать это в цикле, который проверяет условие, чтобы убедиться, что вы не испытали ложного пробуждения.

public runCalculations(Data data){
    globalData=data;
    synchronized(this) {
        calculating=true;
        this.notify();
    }
}
public void run(){
    while(true){
        synchronized(this){
            calculating=false;
            while(!calculating) {
                wait();
            }
        }
        globalData=calculate(globalData);
    }
}

Как правило, большинство людей не советуют использовать ожидание / уведомление и вместо этого рекомендуют использовать исполнителя или, по крайней мере, BlockingQueue. Но для того и другого вам потребуется изменить то, о чем вы сейчас думаете.

...