Zatrzymywanie wątku

0

Witam

Stworzyłem sobie wątek wykonujący pewną symulację. Chciałbym móc zatrzymywać i uruchamiać ten wątek jednym przyciskiem na formatce (takie klasyczne play/pause) ale nie wiem jak to zrobić. wywołanie wait() powoduje wyrzucenie wyjątku java.lang.IllegalMonitorStateException.

Watek uruchamiam przez exekutor newCachedThreadPool.

Pomóżcie

1

Poczytaj sobie o wait() i notify() oraz tym, jak to stosowac ;) Jak rozumiem w watku masz jakas petle, wiec po prostu sprawdzaj w kazdym jej obrocie, czy mozesz przejsc (wait()). A przycisk niech robi na zmiane wait()/notify() na tym samym obiekcie.
Patrz komentarze...

1

Pytanie kardynalne: Czy ty chcesz wstrzymywać wątek i później go kontynuować? Czy może przerwać obecnie działający i rozpocząć nowy.
W pierwsztym przypadku synchroniczne metody wait() notyfy notyfyAll() i join() są do tego bardzo dobrym rozwiązaniem. Wyjątkiem wypluwało Tobie, bo wywoływałeś te metody nie synchronizując wywołań (na dowolnym obiekcie). (blok synchronized(object){} lub metody synchroniczne)

w drugim przypadku podejścia masz 2.

W swoim wątku zadaniowym musisz uwzględnić sprawdzanie czy wątek nie został przerwany. Służy do tego metoda isInterupted() która sprawdza (i uwaga - po odczycie kasuje) czy wątek został przerwany po przez wywołanie asynchroniczne metody interupt() na obiekcie reprezentującym ten wątek. Trzeba się tutaj również liczyć z tym, że jeżeli Twój roboczy thread się gdzieś usypia, czeka na notify() lub blokuje się po przez operacje IO i pochodne, będzie sypało wyjątkami typu threadInterruptedException(czy jakoś tak. Wyjątek będzie wyrzucony przez roboczy wątek, nie przez wątek z którego metoda interrupt() była wywoływana). O tym fakcie jednak poinformuje cię IDE w większości przypadków.

Jeżeli mowa o zatrzymaniu wątku to również interrupt() a na drugim kliknięciu swojego buttona startujesz nowy wątek (tworząc nowego Thread'a i Runnable'a)

Drugim, bardziej już nowoczesnym, rozwiązanym systemowo podejściem jest wykorzystanie tzw "egzekutorów" czyli wątków roboczych których naturą jest wykonywanie zadań z puli zadań po kolei.
Działa to w ten sposób, że tworzysz sobie pule wątków roboczych - sprowadza się to to jednej instrukcji tak naprawdę. Następnie do tej puli dodajesz obiekty typu callable (również runnable) które są określonymi zadaniami. Logika puli wątków roboczych sama odpowiada za przydzielanie tych zadań do wątków.
Zaletą tego rozwiązania jest

  • praca na wielu rdzeniach
  • Skracamy czas wykonania dla wielu zadań - tworzenie nowego wątku (obiektu thread) jest bardzo zasobożerne, przez co oszczędzamy zasoby bo określona liczba obiektów jest tworzona raz(nie do końca prawda, ale to zależy od typu puli - może być fixed(stała ilość), ale też może być rozszerzalna)
  • bardzo dobrze sprawdza się przy
  • Systemowo jest rozwiązane przerywanie obecnych zadań - nie wiem jak ale jest ;P

W Twoim przypadku starczy albo pula wątków składająca się z 1 wątku, albo obsługa przerwania wątku - ja jednego roboczego preferuje tą drugą metodę.
Sam używam takiego rozwiązania przy ładowaniu cykicznym ładowaniu obrazów. Wątek roboczy biega w pętli nieskończonej, czeka na wywołanie notify() (lub na przerwanie:)), wybudza się, robi swoje zadanie i z powrotem do uśpienia. Działa czarująco

Sorry for long post - in 9gag style here is a potato
Potato ocenzurowano;]

1 użytkowników online, w tym zalogowanych: 0, gości: 1