logo

Cykl życia wątku (stany wątku)

W Javie wątek zawsze istnieje w jednym z poniższych stanów. Te stany to:

  1. Nowy
  2. Aktywny
  3. Zablokowano / Oczekuję
  4. Czasowe oczekiwanie
  5. Zakończony

Wyjaśnienie różnych stanów wątków

Nowy: Za każdym razem, gdy tworzony jest nowy wątek, zawsze znajduje się on w nowym stanie. Dla wątku w nowym stanie kod nie został jeszcze uruchomiony, a zatem nie rozpoczął się jego wykonywanie.

Aktywny: Kiedy wątek wywołuje metodę start(), przechodzi z nowego stanu do stanu aktywnego. Stan aktywny zawiera w sobie dwa stany: jeden to nadający się do uruchomienia , a drugi jest działanie .

    Możliwość uruchomienia:Wątek, który jest gotowy do uruchomienia, jest następnie przenoszony do stanu umożliwiającego wykonanie. W stanie nadającym się do uruchomienia wątek może być uruchomiony lub gotowy do działania w dowolnym momencie. Obowiązkiem osoby planującej wątek jest zapewnienie czasu działania wątku, tj. przeniesienie wątku do stanu uruchomionego.
    Program wdrażający wielowątkowość otrzymuje ustalony fragment czasu dla każdego pojedynczego wątku. Każdy wątek działa przez krótki okres czasu, a kiedy przydzielony mu przedział czasu się skończy, wątek dobrowolnie oddaje procesor innemu wątkowi, dzięki czemu inne wątki również mogą działać przez swój wycinek czasu. Ilekroć taki scenariusz ma miejsce, wszystkie wątki, które chcą działać i czekają na swoją kolej, znajdują się w stanie nadającym się do uruchomienia. W stanie umożliwiającym wykonanie istnieje kolejka, w której znajdują się wątki.Działanie:Kiedy wątek pobiera procesor, przechodzi ze stanu uruchomionego do stanu uruchomionego. Ogólnie rzecz biorąc, najczęstszą zmianą stanu wątku jest przejście z uruchomionego do uruchomionego i ponownie do uruchomionego.

Zablokowany lub oczekujący: Ilekroć wątek jest nieaktywny przez pewien czas (nie na stałe), wówczas albo wątek jest w stanie zablokowanym, albo w stanie oczekiwania.

Na przykład wątek (powiedzmy, że ma nazwę A) może chcieć wydrukować pewne dane z drukarki. Jednak w tym samym czasie drugi wątek (powiedzmy, że ma nazwę B) używa drukarki do wydrukowania niektórych danych. Dlatego wątek A musi poczekać, aż wątek B użyje drukarki. Zatem wątek A jest w stanie zablokowanym. Wątek w stanie zablokowanym nie jest w stanie wykonać żadnego wykonania, a zatem nigdy nie zużywa żadnego cyklu jednostki centralnej (CPU). Można zatem powiedzieć, że wątek A pozostaje bezczynny do czasu, aż program planujący wątki ponownie aktywuje wątek A, który znajduje się w stanie oczekiwania lub jest zablokowany.

Kiedy główny wątek wywołuje metodę Join(), mówi się, że wątek główny znajduje się w stanie oczekiwania. Następnie wątek główny czeka, aż wątki podrzędne zakończą swoje zadania. Gdy wątki podrzędne zakończą swoje zadanie, do wątku głównego wysyłane jest powiadomienie, co ponownie przenosi wątek ze stanu oczekiwania do stanu aktywnego.

Jeśli wiele wątków znajduje się w stanie oczekiwania lub zablokowania, obowiązkiem osoby planującej wątki jest określenie, który wątek wybrać, a który odrzucić, po czym wybrany wątek może zostać uruchomiony.

Czas oczekiwania: Czasami czekanie prowadzi do głodu. Na przykład wątek (jego nazwa to A) wszedł do sekcji krytycznej kodu i nie chce opuścić tej sekcji krytycznej. W takim scenariuszu kolejny wątek (jego nazwa to B) musi czekać w nieskończoność, co prowadzi do głodu. Aby uniknąć takiego scenariusza, wątkowi B nadawany jest określony czasowo stan oczekiwania. W związku z tym wątek znajduje się w stanie oczekiwania przez określony czas, a nie na zawsze. Prawdziwym przykładem oczekiwania czasowego jest wywołanie metody Sleep() w konkretnym wątku. Metoda Sleep() umieszcza wątek w stanie oczekiwania. Po upływie tego czasu wątek budzi się i rozpoczyna wykonywanie od momentu, w którym opuścił wcześniej.

Zakończony: Wątek osiąga stan zakończenia z następujących powodów:

  • Kiedy wątek zakończy swoje zadanie, istnieje lub normalnie się kończy.
  • Nienormalne zakończenie:Występuje w przypadku nietypowych zdarzeń, takich jak nieobsługiwany wyjątek lub błąd segmentacji.

Zakończony wątek oznacza, że ​​wątku nie ma już w systemie. Innymi słowy, wątek jest martwy i nie ma możliwości jego odrodzenia (aktywnego po zabiciu).

Poniższy diagram przedstawia różne stany związane z cyklem życia wątku.

Cykl życia wątku Java

Implementacja stanów wątków

W Javie bieżący stan wątku można uzyskać za pomocą metody Wątek.getState() metoda. The java.lang.Thread.State Klasa Java udostępnia stałe ENUM reprezentujące stan wątku. Te stałe to:

typy złączeń w rdbms
 public static final Thread.State NEW 

Reprezentuje pierwszy stan wątku, czyli stan NOWY.

 public static final Thread.State RUNNABLE 

Reprezentuje stan możliwy do uruchomienia. Oznacza to, że wątek oczekuje w kolejce na uruchomienie.

 public static final Thread.State BLOCKED 

Reprezentuje stan zablokowania. W tym stanie wątek oczekuje na uzyskanie blokady.

 public static final Thread.State WAITING 

Reprezentuje stan oczekiwania. Wątek przejdzie do tego stanu, gdy wywoła metodę Object.wait() lub metodę Thread.join() bez przekroczenia limitu czasu. Wątek w stanie oczekiwania oczekuje na zakończenie swojego zadania przez inny wątek.

 public static final Thread.State TIMED_WAITING 

Reprezentuje czasowy stan oczekiwania. Główną różnicą między oczekiwaniem a czekaniem określonym w czasie jest ograniczenie czasowe. Oczekiwanie nie ma ograniczenia czasowego, podczas gdy oczekiwanie czasowe ma ograniczenie czasowe. Wątek wywołujący następującą metodę osiąga stan oczekiwania.

  • spać
  • dołącz z limitem czasu
  • poczekaj z przekroczeniem limitu czasu
  • parkDo
  • parkNanos
 public static final Thread.State TERMINATED 

Reprezentuje końcowy stan wątku, który jest zakończony lub martwy. Zakończony wątek oznacza, że ​​zakończył swoje wykonywanie.

Program Java do demonstrowania stanów wątków

Poniższy program Java pokazuje niektóre stany wątku zdefiniowane powyżej.

Nazwa pliku: ThreadState.java

 // ABC class implements the interface Runnable class ABC implements Runnable { public void run() { // try-catch block try { // moving thread t2 to the state timed waiting Thread.sleep(100); } catch (InterruptedException ie) { ie.printStackTrace(); } System.out.println('The state of thread t1 while it invoked the method join() on thread t2 -'+ ThreadState.t1.getState()); // try-catch block try { Thread.sleep(200); } catch (InterruptedException ie) { ie.printStackTrace(); } } } // ThreadState class implements the interface Runnable public class ThreadState implements Runnable { public static Thread t1; public static ThreadState obj; // main method public static void main(String argvs[]) { // creating an object of the class ThreadState obj = new ThreadState(); t1 = new Thread(obj); // thread t1 is spawned // The thread t1 is currently in the NEW state. System.out.println('The state of thread t1 after spawning it - ' + t1.getState()); // invoking the start() method on // the thread t1 t1.start(); // thread t1 is moved to the Runnable state System.out.println('The state of thread t1 after invoking the method start() on it - ' + t1.getState()); } public void run() { ABC myObj = new ABC(); Thread t2 = new Thread(myObj); // thread t2 is created and is currently in the NEW state. System.out.println('The state of thread t2 after spawning it - '+ t2.getState()); t2.start(); // thread t2 is moved to the runnable state System.out.println('the state of thread t2 after calling the method start() on it - ' + t2.getState()); // try-catch block for the smooth flow of the program try { // moving the thread t1 to the state timed waiting Thread.sleep(200); } catch (InterruptedException ie) { ie.printStackTrace(); } System.out.println('The state of thread t2 after invoking the method sleep() on it - '+ t2.getState() ); // try-catch block for the smooth flow of the program try { // waiting for thread t2 to complete its execution t2.join(); } catch (InterruptedException ie) { ie.printStackTrace(); } System.out.println('The state of thread t2 when it has completed it's execution - ' + t2.getState()); } } 

Wyjście:

 The state of thread t1 after spawning it - NEW The state of thread t1 after invoking the method start() on it - RUNNABLE The state of thread t2 after spawning it - NEW the state of thread t2 after calling the method start() on it - RUNNABLE The state of thread t1 while it invoked the method join() on thread t2 -TIMED_WAITING The state of thread t2 after invoking the method sleep() on it - TIMED_WAITING The state of thread t2 when it has completed it's execution - TERMINATED 

Wyjaśnienie: Za każdym razem, gdy tworzymy nowy wątek, wątek ten osiąga nowy stan. Kiedy w wątku zostanie wywołana metoda start(), program planujący wątki przenosi ten wątek do stanu umożliwiającego wykonanie. Za każdym razem, gdy metoda Join() jest wywoływana w dowolnej instancji wątku, bieżący wątek wykonujący tę instrukcję musi poczekać, aż wątek zakończy wykonywanie, tj. przeniesie ten wątek do stanu zakończonego. Dlatego też, zanim końcowa instrukcja print zostanie wydrukowana na konsoli, program wywołuje metodę Join() w wątku t2, powodując, że wątek t1 czeka, aż wątek t2 zakończy wykonywanie, a tym samym wątek t2 przejdzie do stanu zakończonego lub martwego . Wątek t1 przechodzi w stan oczekiwania, ponieważ oczekuje na zakończenie wykonywania wątku t2, ponieważ wywołał metodę Join() w wątku t2.