Wątki w Javie: Wprowadzenie do Programowania Wielowątkowego

Java jest jednym z najpopularniejszych języków programowania, a jej wsparcie dla wielowątkowości jest jednym z kluczowych powodów tej popularności. Wątki są podstawą programowania wielowątkowego w Javie, umożliwiając tworzenie aplikacji, które mogą wykonywać wiele zadań jednocześnie. W tym artykule przyjrzymy się szczegółowo wątkom w Javie, ich tworzeniu, zarządzaniu i optymalizacji.


Czym są wątki?

Wątek to niezależna ścieżka wykonania w programie. W Javie każdy program ma co najmniej jeden wątek – tzw. main thread. Gdy aplikacja wymaga równoległego wykonywania wielu zadań, dodatkowe wątki są tworzone i zarządzane. Wątki pozwalają na:

  • Równoległe wykonywanie kodu,
  • Optymalizację wykorzystania CPU,
  • Tworzenie responsywnych aplikacji, takich jak interfejsy użytkownika czy serwery obsługujące wielu klientów jednocześnie.

Tworzenie Wątków w Javie

Java oferuje kilka sposobów tworzenia wątków:

1. Dziedziczenie po klasie Thread

Pierwszym sposobem jest dziedziczenie po klasie Thread i nadpisanie metody run():

class MyThread extends Thread {     @Override     public void run() {         System.out.println("Wątek działa: " + Thread.currentThread().getName());     } } public class Main {     public static void main(String[] args) {         MyThread thread = new MyThread();         thread.start(); // Uruchomienie wątku     } }

Metoda start() rozpoczyna nowy wątek i wywołuje metodę run().

2. Implementacja interfejsu Runnable

Lepszym podejściem jest implementacja interfejsu Runnable, ponieważ Java nie wspiera wielodziedziczenia klas, ale pozwala na implementację wielu interfejsów:

class MyRunnable implements Runnable {     @Override     public void run() {         System.out.println("Wątek działa: " + Thread.currentThread().getName());     } } public class Main {     public static void main(String[] args) {         Thread thread = new Thread(new MyRunnable());         thread.start();     } }

3. Wyrażenia lambda

Od wersji Javy 8 można wykorzystać wyrażenia lambda, co upraszcza kod:

public class Main {     public static void main(String[] args) {         Thread thread = new Thread(() -> {             System.out.println("Wątek działa: " + Thread.currentThread().getName());         });         thread.start();     } }

Zarządzanie Wątkami

W Javie istnieje wiele narzędzi i metod do zarządzania wątkami. Oto najważniejsze z nich:

1. Priorytety Wątków

Każdy wątek ma priorytet, który można ustawić za pomocą metody setPriority():

thread.setPriority(Thread.MAX_PRIORITY); // Ustawienie najwyższego priorytetu

Priorytety pomagają zarządzać tym, który wątek ma większe znaczenie, ale ich wykorzystanie zależy od systemu operacyjnego.

2. Synchronizacja

Gdy wiele wątków współdzieli zasoby, konieczna jest synchronizacja, aby uniknąć konfliktów. Java oferuje mechanizm synchronizacji za pomocą słowa kluczowego synchronized:

class SharedResource {     synchronized void display(String message) {         System.out.println("[Start] " + message);         try {             Thread.sleep(1000);         } catch (InterruptedException e) {             e.printStackTrace();         }         System.out.println("[End] " + message);     } } public class Main {     public static void main(String[] args) {         SharedResource resource = new SharedResource();         Thread t1 = new Thread(() -> resource.display("Wątek 1"));         Thread t2 = new Thread(() -> resource.display("Wątek 2"));         t1.start();         t2.start();     } }

3. Zarządzanie cyklem życia wątku

Wątek przechodzi przez różne stany: Nowy, Gotowy do uruchomienia, Uruchomiony, Zatrzymany, Zakończony. Można to kontrolować za pomocą metod:

  • start() – uruchamia wątek,
  • join() – czeka na zakończenie danego wątku,
  • interrupt() – przerywa działanie wątku.

Wątki w Javie: Zaawansowane Tematy

1. ExecutorService

Zarządzanie wieloma wątkami może być trudne, dlatego Java oferuje ExecutorService, który umożliwia wygodne zarządzanie pulą wątków:

import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class Main {     public static void main(String[] args) {         ExecutorService executor = Executors.newFixedThreadPool(3);         for (int i = 0; i < 5; i++) {             executor.submit(() -> {                 System.out.println("Wątek działa: " + Thread.currentThread().getName());             });         }         executor.shutdown();     } }

2. CompletableFuture

CompletableFuture pozwala na programowanie asynchroniczne:

import java.util.concurrent.CompletableFuture; public class Main {     public static void main(String[] args) {         CompletableFuture.supplyAsync(() -> {             return "Wynik asynchroniczny";         }).thenAccept(result -> {             System.out.println(result);         });     } }

3. Synchronizatory

Java oferuje zaawansowane mechanizmy synchronizacji, takie jak:

  • Semaphore,
  • CountDownLatch,
  • CyclicBarrier.

Potencjalne Problemy w Programowaniu Wielowątkowym

1. Problemy z synchronizacją

Brak synchronizacji może prowadzić do niespójności danych. Przykładem jest problem wyścigu (race condition).

2. Przepełnienie pamięci

Zbyt wiele wątków może powodować przepełnienie stosu pamięci wątku (stack overflow).

3. Głodzenie wątków (thread starvation)

Wątki o niskim priorytecie mogą nigdy nie dostać czasu procesora, jeśli wątki o wyższym priorytecie dominują.


Java dostarcza bogaty zestaw narzędzi do pracy z wątkami, które pozwalają programistom na tworzenie skalowalnych, wydajnych i responsywnych aplikacji. W miarę rozwijania projektu warto zagłębiać się w zaawansowane mechanizmy i korzystać z narzędzi oferowanych przez platformę.