Mam wątek, który aktualizuje jego stan od czasu do czasu i chcę, aby drugi wątek mógł poczekać na pierwszy wątek do zrobienia. Coś takiego:Oczekiwanie na wydarzenie w Javie - jak trudne jest to?
Thread 1:
while(true) {
...do something...
foo.notifyAll()
...wait for some condition that might never happen...
...
}
Thread 2:
...
foo.wait();
...
Teraz to wygląda ładnie i wszystko chyba gwintu 1 za notifyAll() biegnie przed gwintu 2 na wait(), w którym to przypadku gwintu 2 czeka aż gwintu 1 poinformuje podmiot ponownie (która nigdy nie może się zdarzyć) .
Moi możliwe rozwiązania:
a) mogę użyć CountDownLatch lub przyszłości, ale oba mają ten problem, że właściwie tylko uruchomić raz. Oznacza to, że w pętli while 1 wątku, musiałbym utworzyć nowe foo, aby czekać za każdym razem, a wątek 2 musiałby zapytać, na które foo czekać. Mam złe przeczucia prostu pisząc
while(true) {
foo = new FutureTask();
...
foo.set(...);
...wait for a condition that might never be set...
...
}
a obawiam się, że w foo = new FutureTask(), co się dzieje, gdy ktoś czekał na starym foo (dla „jakiegoś powodu”, ustaw nie został powołany, na przykład błąd w obsłudze wyjątków)?
b) Czy mogę użyć semafora:
class Event {
Semaphore sem;
Event() { sem = new Semaphore(1); sem . }
void signal() { sem.release(); }
void reset() { sem.acquire(1); }
void wait() { if (sem.tryAcquire(1)) { sem.release(); } }
}
Ale obawiam się, że jest jakaś sytuacja wyścigu, jeśli wiele wątków są wait() ing dla niego natomiast drugi sygnał() s i reset () s.
Pytanie:
Czy nic w API Java, który przypomina zachowanie zdarzeń systemu Windows? Lub, jeśli gardzisz Windows, coś w stylu golang's WaitGroup (to znaczy CountDownLatch, który zezwala na countUp())? Byle co?
Jak to zrobić ręcznie:
Temat 2 nie może po prostu poczekać z powodu fałszywej wznawianiu i Java nie ma sposobu, aby wiedzieć, dlaczego Object.wait() zwracane. Potrzebuję zmiennej warunkowej, która zapisuje, czy zdarzenie jest sygnalizowane, czy nie. Wątek 2:
synchronized(foo) {
while(!condition) {
foo.wait();
}
}
I wątek 1 oczywiście ustawia warunek na true w zsynchronizowanym bloku. Dzięki tygodniom na podpowiedź!
Czy istnieje klasa, która owija to zachowanie?
Czy muszę skopiować i wkleić cały kod?
Jaki problem rzeczywiście stara się rozwiązać? Chociaż jestem pewien, że ten problem można rozwiązać, nadal chciałbym zapytać, więc wiemy, że jest to właściwe rozwiązanie Twojego problemu. Ten rodzaj bałaganu z wątkami i semaforami, mimo że jest dobrze zrozumiany, jest często podatny na błędy z powodu drobnych błędów, więc może istnieć bardziej czytelny, łatwy do zrozumienia sposób robienia tego, co chcesz osiągnąć. W szczególności brzmi to jak zwykły wzorzec głośnika, w którym słuchacze rejestrują się ze źródłem zdarzeń, byłoby bardziej odpowiednie. – Thor84no
Tak, detektor zdarzeń rozwiąże problem, umożliwiając aktualizację wątku 1 "push". Jest to zwykle preferowana metoda, np. w środowisku serwera. Jednak od czasu do czasu natknąłem się na problem "ciągnięcia" za aktualizację wątku i do tej pory nie miałem czystego rozwiązania. – Kosta