Wprowadzenie do stanu wątku Java z przykładem — cykl życia wątku

Opublikowany: 2019-01-11
Wprowadzenie do stanu wątku Java z przykładem

Stany wątków

Poniższy diagram ilustruje różne stany, w jakich może znajdować się wątek Javy w dowolnym momencie swojego życia oraz które wywołania metod powodują przejście do innego stanu. Ten diagram nie jest kompletnym diagramem stanów skończonych, ale raczej przeglądem bardziej interesujących i powszechnych aspektów życia wątku.

Jesteś we właściwym miejscu, jeśli masz którekolwiek z poniższych pytań:

  • Cykl życia wątku w Javie
  • Cykl życia i stany wątku w Javie
  • Zrozumienie stanów wątków Java

Pozostała część tej strony omawia Thread's life cycle pod względem jego stanu.

Stan wątku Java z przykładem

Nowy wątek

Poniższa instrukcja tworzy nowy wątek, ale go nie uruchamia, pozostawiając wątek w stanie oznaczonym na diagramie jako Nowy wątek.

Gdy wątek jest w stanie New Thread , jest to po prostu pusty obiekt Thread. Nie przydzielono jeszcze żadnych zasobów systemowych. Tak więc, gdy wątek jest w tym stanie, możesz tylko uruchomić wątek lub go zatrzymać; wywołanie jakiejkolwiek innej metody poza start() lub stop() , gdy wątek jest w tym stanie, nie ma sensu i powoduje wyjątek IllegalThreadStateException.

Możliwość uruchomienia

Rozważmy teraz te dwa wiersze kodu:

Metoda start() tworzy zasoby systemowe niezbędne do uruchomienia wątku, planuje uruchomienie wątku i wywołuje metodę run() wątku. W tym momencie wątek jest w stanie „Runnable”. Ten stan nazywa się „Uruchomiony”, a nie „Uruchomiony”, ponieważ wątek może w rzeczywistości nie działać, gdy jest w tym stanie. Wiele komputerów ma jeden procesor, co uniemożliwia jednoczesne uruchamianie wszystkich wątków „Runnable”.

Tak więc system Java Runtime musi zaimplementować schemat planowania, który współdzieli procesor między wszystkimi „Runnable” wątkami. Jednak w większości przypadków stan „Uruchamialny” można traktować jako po prostu „Uruchomiony”. Kiedy wątek jest uruchomiony – jest „Runnable” i jest bieżącym wątkiem – instrukcje w jego run() są wykonywane sekwencyjnie.

Nie można uruchomić

Wątek przechodzi w stan Not Runnable można uruchomić, gdy wystąpi jedno z tych czterech zdarzeń:

  • ktoś wywołuje jego metodę suspend()
  • ktoś wywołuje jego metodę sleep()
  • wątek używa swojej metody wait() do oczekiwania na zmienną warunku
  • wątek blokuje się na we/wy.

Na przykład pogrubiona linia w tym fragmencie kodu

myThread na 10 sekund (10 000 milisekund). W ciągu tych 10 sekund, nawet gdyby procesor stał się dostępny, myThread nie działałby. Po upływie 10 sekund myThread staje się „Runnable” i teraz, jeśli procesor będzie dostępny, myThread będzie działać.

Dla każdego z „wejść” do stanu „Nie można uruchomić” wymienionego powyżej, istnieje określona i odrębna droga ucieczki, która przywraca wątek do stanu „Uruchamialny”. Droga ewakuacyjna działa tylko dla odpowiadającego jej „wejścia”. Na przykład, jeśli wątek został uśpiony, musi upłynąć określona liczba milisekund, zanim wątek ponownie stanie się uruchamialny. Wywołanie resume() w uśpionym wątku nie ma żadnego efektu.

Poniżej wskazano drogę ucieczki dla każdego wejścia w stan „Nie da się uruchomić”.

  • Jeśli wątek został uśpiony, musi upłynąć określona liczba milisekund.
  • Jeśli wątek został zawieszony, ktoś musi wywołać jego metodę resume() .
  • Jeśli wątek czeka na zmienną warunku, dowolny obiekt, który jest właścicielem zmiennej, musi ją porzucić, wywołując notify() lub notifyAll() .
  • Jeśli wątek jest zablokowany na we/wy, określone polecenie we/wy musi zostać zakończone.
samouczek-wątku java

Martwy

Nić może umrzeć na dwa sposoby: albo z przyczyn naturalnych, albo przez zabicie (zatrzymanie). Wątek umiera naturalnie, gdy jego metoda run() kończy się normalnie. Na przykład pętla while w tej metodzie jest pętlą skończoną — wykona iterację 100 razy, a następnie zakończy działanie.

Wątek z tą metodą run() umrze naturalnie po zakończeniu pętli i zakończeniu metody run() .

Możesz także zabić wątek w dowolnym momencie, wywołując jego metodę stop() . Ten fragment kodu.

tworzy i uruchamia myThread a następnie usypia bieżący wątek na 10 sekund. Gdy bieżący wątek się budzi, pogrubiona linia w segmencie kodu zabija myThread .

Metoda stop() rzuca obiekt ThreadDeath w wątku, aby go zabić. Tak więc, gdy wątek zostanie zabity w ten sposób, umiera asynchronicznie. Wątek umrze, gdy faktycznie otrzyma wyjątek ThreadDeath.

Niedozwolony wyjątek stanu wątku

System środowiska wykonawczego zgłasza wyjątek IllegalThreadStateException, gdy wywoływana jest metoda w wątku, a stan tego wątku nie zezwala na wywołanie tej metody. Na przykład, IllegalThreadStateException jest generowany, gdy wywołasz suspend() w wątku, który nie jest „Runnable”.

Jak pokazano w różnych przykładach wątków do tej pory w tej lekcji, po wywołaniu metody wątku, która może zgłosić wyjątek, należy albo przechwycić i obsłużyć wyjątek, albo zadeklarować, że metoda wywołująca zgłasza nieprzechwycony wyjątek.

Metoda isAlive()

I ostatnie słowo o stanie wątku: interfejs programistyczny dla klasy Thread zawiera metodę o nazwie isAlive() . Funkcja isAlive() zwraca wartość true, jeśli wątek został uruchomiony, a nie zatrzymany. Tak więc, jeśli metoda isAlive() zwróci wartość false , wiesz, że wątek jest „Nowym Wątkiem” lub „Martwym”.

Jeśli metoda isAlive() zwróci true , wiesz, że wątek jest albo „Możliwy do uruchomienia” lub „Nie można go uruchomić”. Nie można odróżnić wątku „Nowego” od „Martwego”; nie można też odróżnić wątku „Runnable” od wątku „Not Runnable”.

Patrząc na złożone przykłady wątków, znalazłem ten naprawdę świetny samouczek w sieci. Każdy powinien to uważnie przeczytać.