/ / new w wielowątkowości - jak korzystać z wait () i notify () w Javie? - Java, wielowątkowość, poczekaj, powiadom

nowość w wielowątkowości - jak używać wait () i notify () w java? - Java, wielowątkowość, czekaj, powiadamiaj

Próbuję napisać program z 2 klasami, akontroler i klasa, która wykonuje wiele obliczeń. Kontroler tworzy kilka instancji drugiej klasy, a następnie każe im wszystkim rozpocząć obliczenia (równolegle). Każdy z nich wraca po zakończeniu, a kontroler wznawia, a następnie, po pewnym czasie, kontroler przekazuje im nowe dane i ponownie uruchamia obliczenia.
Idealnie byłoby móc wywołać start () zparametry, ale to nie jest możliwe, więc kontroler wywołuje metodę w kalkulatorze, która przechowuje dane w globalnej, a następnie uruchamia wątek obliczeniowy i zwraca, co działa, dopóki nie spróbuję ponownie uruchomić wątku, i mówi mi wątek jest martwy. Więc próbuję uczynić z uruchomienia nieskończoną pętlę, która tylko czeka na powiadomienie, uruchamia obliczenia, przechowuje wyniki w globalnym, aby sterownik mógł je później odzyskać, a następnie wznawia czekanie. Więc coś takiego:

//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;
}
}

Odpowiedzi:

4 dla odpowiedzi № 1

Musisz uzyskać włączony monitor this zanim zadzwonisz notify(). Także kiedy dzwonisz wait() powinieneś to zrobić w pętli, która sprawdza warunek, aby upewnić się, że nie wystąpiło fałszywe budzenie.

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

Ogólnie rzecz biorąc, większość ludzi odradzałabyza pomocą funkcji wait / powiadom i zamiast tego zalecamy użycie Executora lub przynajmniej BlockingQueue. Ale oba z nich wymagałyby przeprojektowania tego, co obecnie myślisz.