Historia pytania:
W Javie wsparcie dla wielowątkowości zostało wprowadzone od samego początku. Wątki pozwalają na jednoczesne wykonywanie kilku zadań, efektywnie wykorzystując procesory wielordzeniowe. JVM zapewnia warstwę abstrakcji nad wątkami systemu operacyjnego.
Problem:
Tworzenie, zarządzanie i zakończenie wątków wymaga jasnego zrozumienia ich cyklu życia, synchronizacji oraz możliwych stanów wyścigu. Nieostrożne użycie wątków może prowadzić do deadlocków, niepoprawnego dostępu do zasobów oraz skomplikowanych logów błędów.
Rozwiązanie:
W Javie wątki można tworzyć przez rozszerzenie klasy Thread lub implementację interfejsu Runnable, a także przy użyciu nowoczesnych narzędzi typu ExecutorService. Ważne jest poprawne zakończenie wątków, zarządzanie ich cyklem życia oraz synchronizacja dostępu do danych współdzielonych.
Przykład tworzenia i zakończenia wątku:
class MyRunnable implements Runnable { public void run() { System.out.println("Wątek działa"); } } public class ThreadExample { public static void main(String[] args) { Thread t = new Thread(new MyRunnable()); t.start(); // uruchomienie wątku try { t.join(); // oczekiwanie na zakończenie } catch (InterruptedException e) { e.printStackTrace(); } } }
Kluczowe cechy:
start(), a nie run() (w przeciwnym razie nie będzie rzeczywistego równoległego przetwarzania)join()start spowoduje IllegalThreadStateExceptionCzy można ponownie uruchomić wątek po jego zakończeniu?
Nie. Po zakończeniu wątek uznawany jest za "martwy", ponowne wywołanie start() spowoduje IllegalThreadStateException.
Jaka jest różnica między wywołaniem t.run() a t.start()?
t.run() po prostu wywoła metodę run w bieżącym wątku, nie tworząc nowego wątku wykonawczego. Tylko t.start() tworzy oddzielny wątek systemu operacyjnego.
Co się stanie, jeśli wątek zakończy się z nieobsłużonym wyjątkiem?
Jeśli zostanie zgłoszony nieobsłużony wyjątek, wątek zakończy się awaryjnie, jego stos śladowy zostanie wyświetlony w strumieniu błędów, a inne wątki nie zostaną dotknięte.
run() zamiast start()InterruptedException)Programista uruchamia wątek metodą run(), myśląc, że działa równolegle z main, ale w rzeczywistości wszystko wykonuje się sekwencyjnie.
Zalety:
Wady:
Prawidłowe użycie start(), poprawna obsługa wyjątków, zastosowanie join() do oczekiwania na zakończenie wątków.
Zalety:
Wady: