Czym jest zakleszczenie (deadlock) w Javie?

Zakleszczenie w Javie, znane również jako deadlock, to sytuacja w programowaniu wielowątkowym, gdzie dwa lub więcej wątków blokuje się nawzajem, czekając na zasoby, które są trzymane przez inny wątek. W rezultacie żaden z wątków nie może kontynuować swojej pracy. Jest to problem typowy dla aplikacji wielowątkowych i może prowadzić do spadku wydajności lub nawet całkowitego zatrzymania aplikacji.

Przykład ilustrujący deadlock w Javie

W poniższym przykładzie zasymulujemy proste zakleszczenie za pomocą dwóch wątków, które wzajemnie na siebie czekają. Każdy wątek próbuje zablokować dwa zasoby, ale w odwrotnej kolejności.

public class DeadlockExample {
    // Pierwszy zasób
    private static Object resource1 = new Object();
    // Drugi zasób
    private static Object resource2 = new Object();

    public static void main(String[] args) {
        // Tworzenie pierwszego wątku
        Thread thread1 = new Thread(() -> {
            synchronized (resource1) { // Blokowanie pierwszego zasobu
                System.out.println("Thread 1: Zablokowany zasób 1");

                try {
                    Thread.sleep(100); // Symulacja pracy
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }

                synchronized (resource2) { // Próba zablokowania zasobu 2
                    System.out.println("Thread 1: Zablokowany zasób 2");
                }
            }
        });

        // Tworzenie drugiego wątku
        Thread thread2 = new Thread(() -> {
            synchronized (resource2) { // Blokowanie drugiego zasobu
                System.out.println("Thread 2: Zablokowany zasób 2");

                try {
                    Thread.sleep(100); // Symulacja pracy
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }

                synchronized (resource1) { // Próba zablokowania zasobu 1
                    System.out.println("Thread 2: Zablokowany zasób 1");
                }
            }
        });

        // Uruchomienie obu wątków
        thread1.start();
        thread2.start();
    }
}

Omówienie kodu

  • Definicja zasobów: Zadeklarowaliśmy dwa obiekty resource1 i resource2, które będą wykorzystywane jako zasoby do blokowania.
  • Definicja wątków: Stworzyliśmy dwa wątki thread1 i thread2. Każdy z nich próbuje zablokować oba zasoby, ale w odwrotnej kolejności.
  • Zakleszczenie: Każdy wątek zablokuje jeden zasób i czeka na zwolnienie drugiego, które jest już zablokowane przez drugi wątek. W efekcie oba wątki zostają zawieszone, oczekując na siebie nawzajem.

Podsumowanie

Zakleszczenie to poważny problem w aplikacjach wielowątkowych, który wymaga starannego projektowania i zarządzania zasobami, aby go uniknąć. Rozumienie mechanizmów synchronizacji i właściwe stosowanie blokad może pomóc zapobiegać takim problemom w Twojej aplikacji.

Jeżeli chcesz przyśpieszyć swoją naukę tworzenia stron chciałbym polecić mój kurs video Java w którym nauczysz się tego języka od podstaw do zaawansowanych jego aspektów.

Scroll to Top