W programowaniu wielowątkowym w Javie, mechanizm blokad (locks) jest fundamentalnym narzędziem do zarządzania dostępem do zasobów współdzielonych przez wiele wątków. Jednym z typów blokady jest sprawiedliwa blokada (fair lock), która zapewnia, że wątki otrzymują dostęp do zasobu w kolejności ich zgłoszeń. Jest to ważne w przypadkach, gdy chcemy uniknąć sytuacji zwaną „głodzeniem” (starvation), gdzie jeden lub więcej wątków nigdy nie dostają szansy na wykonanie z powodu ciągłego monopolizowania zasobów przez inne wątki.
Przykład użycia sprawiedliwej blokady
Sprawiedliwa blokada w Javie może być realizowana za pomocą klasy ReentrantLock
z pakietu java.util.concurrent.locks
. Poniżej znajduje się kompletny przykład kodu, który demonstruje użycie tej blokady w aplikacji wielowątkowej.
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.Lock;
public class FairLockExample {
// Zmienna dla blokady; ustawiona na 'true' dla sprawiedliwości
private final Lock lock = new ReentrantLock(true);
// Metoda demonstrująca działanie blokady
public void printJob(Object document) {
lock.lock(); // Rozpoczęcie blokady
try {
// Symulacja zadania wydruku
System.out.println(Thread.currentThread().getName()
+ ": Drukowanie dokumentu " + document);
Thread.sleep(1000); // Czas drukowania
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
lock.unlock(); // Zwolnienie blokady
}
}
public static void main(String[] args) {
FairLockExample printer = new FairLockExample();
// Tworzenie wątków
Thread t1 = new Thread(() -> printer.printJob("Dokument 1"));
Thread t2 = new Thread(() -> printer.printJob("Dokument 2"));
Thread t3 = new Thread(() -> printer.printJob("Dokument 3"));
t1.start();
t2.start();
t3.start();
}
}
Analiza kodu
- ReentrantLock(true): Parametr
true
w konstruktorzeReentrantLock
zapewnia, że kolejność uzyskiwania blokady jest zgodna z kolejnością żądań (sprawiedliwa). - lock() i unlock(): Metody te są używane do blokowania i odblokowywania. Ważne jest, aby zawsze umieszczać wywołanie
unlock()
w blokufinally
w celu zapewnienia, że blokada zostanie zwolniona niezależnie od tego, czy operacje międzylock()
aunlock()
zakończą się pomyślnie, czy wystąpi wyjątek.
Podsumowanie
Sprawiedliwa blokada w Javie jest użyteczna, gdy chcemy zapewnić, że wszystkie wątki mają równą szansę na dostęp do zasobu, unikając problemów takich jak głodzenie. Przykład ten pokazuje, jak można zaimplementować i wykorzystać ReentrantLock
z parametrem sprawiedliwości w praktycznym scenariuszu programistycznym.
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.