Witam
Na początek może przedstawię swój kawałek kodu, którego dotyczy problem, a potem będę wyjaśniał
synchronized void wyswietl_(Uchwyt ap, char ch)
{
if (serwer.liczniku>0)
try{
ap.getTytul_ksiazki().wait();
}
catch(InterruptedException e) { System.out.println("Wyjatek czekania funkcji wyswietlania "+e);}
serwer.licznikw++;
ap.Funkcje_wyswietlania(ch);
serwer.licznikw--;
if (serwer.licznikw==0) {
ap.getTytul_ksiazki().notifyAll();
}
}
synchronized void usun_(Uchwyt ap, char ch)
{
if (serwer.licznikw>0)
{
try{
ap.getTytul_ksiazki().wait();
}
catch(InterruptedException e) { System.out.println("Wyjatek czekania funkcji wyswietlania "+e);}
}
serwer.liczniku++;
ap.Funckje_usuwania(ch);
serwer.liczniku--;
if (serwer.liczniku==0) {
ap.getTytul_ksiazki().notifyAll();
}
}
A teraz o co chodzi - załączone dwie funkcje są metodami klasy komponent_serwera (Socket), która współdziała z klasą główny_serwer (SocketServer) i “rozmawia” z klientem (Socket). “Główny_serwer” jest tutaj pośrednikiem i pilnuje, żeby każdy wywołany klient miał własny komponent_serwera (tworzy go jako nowy wątek).
Idea całego programu to dać możliwość kilku klientom używania wspólnego zasobu, jakim jest w tym wypadku kolekcja “Uchwyt” (jest to klasa z własnymi metodami wyświetlania, dodawania, usuwania itp. objektów typu “Książka”).
O co chodzi z tymi dwoma funkcjami - ano o to, że w moim zadaniu jest dodatkowy warunek: dwóch różnych klientów nie może naraz usuwać i wyświetlać książek z “Uchwytu”. Nie i już
Więc zrobiłem te dwie funkcje, które mają za zadanie sprawdzić czy klient który podał odpowiedni “char ch” może dostąpić zaszczytu wyświetlenia/usunięcia książek. W tym celu sprawdzany jest serwer.liczniku (licznik usunięć) lub serwer.licznikw (licznik wyświetleń) - ideą działania tych liczników jest to, że jeśli licznik usunięć jest równy zero (żaden klient nic nie usuwa) to można bezpiecznie wyświetlać dane i vice versa dla licznika wyświetleń.
Problem polega na tym, że jeśli już jakaś funkcja uśpi wątek (a bo klient chce coś usunąć, a ktoś inny wyświetla i poprawnie blokowany jest dostęp) to już się nie budzi - kiedy ktoś inny skończy wyświetlać dane i “notifyAll” się wykona, to z jakiegoś powodu nie budzi poprzedniego wątku żeby ten mógł sobie spokojnie coś usunąć.
Teraz mogłoby powstać pytanie - czy aby napewno “notyfiAll” się wykonuje wtedy kiedy ma się wykonać? Otóż jak najbardziej - sprawdziłem to poprzez dodanie wiadomości tekstowej tuż obok niego (wewnątrz jego własnego “if”) i jestem pewien że się wykonuje.
ap.getTytul_ksiazki() to wywołanie kolekcji z obiektu “Uchwyt” - chciałem mieć w ten sposób pewność że “wait” i “notifyAll” wykonują się dla tego samego obiektu (kolekcji). Niestety nic to nie zmieniło.
Z góry dziękuję i czekam na jakiś odzew