W tej chwili mam tak. Aplikacja wykorzystująca Swing'a i pobierająca
dane z bazy danych. Pobieranie danych z bazy realizowane jest w osobnym
wątku. W związku z tym, że wątek po pobraniu danych modyfikuje elementy
Swinga korzystam z SwingUtilites.invokeLater(...), co objawia się tym,
że przy pobieraniu większej porcji danych albo gdy klient jest "daleko
od bazy" (dłuższy czas dostępu i przesłania danych z bazy) aplikacja
przestaje na tą chwile odpowiadać.
Wymyśliłem sobie coś takiego (poglądowo):
class xxx extends Thread {
....
boolean continue = true;
public void run () {
while (continue) {
if (zadania_w_kolejce()) {
pobierz_zadanie_z_kolejki_i_wykonaj();
}
else {
continue=false;
}
}
}
....
}
class zadanie {
....
void start() {
wykonaj_zadanie;
Runnable wyniki = new Runnable() {
public void run() {
przetworz_wyniki_i_zmodyfikuj_swinga();
}
};
SwingUtilities.invokeLater(wyniki);
}
....
}
I to wszystko pieknie dziala jak jest jedno zadanie w kolejce do
wykonania. Ale czesto mam sytuacje ze z funkcji
przetworz_wyniki_i_zmodyfikuj_swinga() dodaje kolejne zadania do
kolejki, ale niestety nie "zdążam" bo watek z klasy xxx sie konczy zanim
dodam kolejne zadanie do kolejki. To zrobilem tak, że po
SwingUtilities.invokeLater(updateAComponent); usypiam watek za pomoca
wait() i w funkcji przetworz_wyniki_i_zmodyfikuj_swinga() po zrobieniu
wszystkiego robie notify(). No i znowu mam wyścig watkow i notify jest
wywolywane szybciej niz wait i aplikacja wywala mi sie z wyjatkiem
exception in thread "AWT-EventQueue-0"
java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
...
Jak to powinienem wszystko zsynchronizować zeby działało? Proszę o pomoc.
Dziękuje i pozdrawiam
Kapshel
[ ciach ]
A myslales o uzyciu klasy SwingWorker? sa tam 2 watki, jeden od danych,
drugi od GUI, w kazdym robisz to co potrzeba (ciagniecie danych,
aktualizacja modeli np.) Mozna go jeszcze sobie obudowac np w jakis
dialog z paskiem postepu or sth ;]
--
Krzysztof Wolny
Khem.... ten wyjatek oznacza ze operujesz na monitorze ktorego nie
jestes wlascicielem.... a nie ze notify jest wywolywane przed wait,
wolasz notify spoza synchronizowanego bloku albo z bloku synchronized na
obiekcie innym niz notyfikujesz.
Pozatym czemu calosc przetwarzania danych robisz w threadzie dispatchera
?? Przeciez jezeli to przetwarzanie danych bedzie trwalo dlugo to i tak
ci przyblokuje kolejke komunikatow.
Pozatym taki dispatcher (twoj thread xxx nie powinnien sie konczyc jak
mu braknie zadan w kolejce tylko powinnien na nie czekac).
--
a1