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 № 1Musisz 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.