Teoria współbieżności

Informatyka


Laboratorium 1 - Wątki i synchronizacja w Javie

Wątki a procesy

  1. Rodzaje wątków
    1. Wątki użytkownika (user thread)
    2. Wątki systemowe (kernel thread)
    3. LWP - Lightweight Process (np. w Solaris)
    4. Procesory fizyczne
  2. Przydział wątków do procesorów
    1. Przetwarzanie równoległe
    2. Przetwarzanie współbieżne
    3. Wielozadaniowość kooperacyjna
    4. Wielozadanoiwość z wywłaszczaniem (preemptive)

Wątki w Javie

  1. Tworzenie wątków
    1. Klasa Thread
    2. Interfejs Runnable
    3. API JavaDoc
    4. Anonimowa klasa wewnętrzna:
       
      
      new Thread() {
      	public void run() {
      		for(;;) System.out.println("Thread 1");
      	}
      }.start();
      
      new Thread() {
      	public void run() {
      		for(;;) System.out.println("Thread 2");
      	}
      }.start();
      
      

Wątki w JVM

  1. Architektura JVM: Chapter 5 of Inside the Java Virtual Machine by Bill Venners
    1. Obszary danych: sterta, stos, przestrzeń metod, rejestr licznika programu
    2. Obszary współdzielone między wątkami oraz prywatne
  2. Cykl życia wątku, stany wątku
    1. New, Runnable, Running, Not Running, Dead
  3. Szeregowanie wątkow w Javie
    • Ogólne pojęcia szeregowania: wywłaszczania (preemption), podziału czasu (time-slicing, time-sharing), priorytety.
    • Dokładne zachowanie się wątków jest zależne od platformy.
    • Wątki mogą być zaimplementowane całkowicie w przestrzeni użytkownika lub korzystać z natywnych interfejsów platformy.
    • Wątkom można przypisać priorytety (1-10). Jedyną gwarancją jest to, że wątkom o najwyższym priorytecie zostanie przydzielony CPU. Wątki o niższym priorytecie mają gwarancję przydziału CPU tylko wtedy, gdy wątki z wyższym priorytetem są zablokowane, w przeciwnym wypadku nie ma tej gwarancji.
    • Specyfikacja nie zakłada podziału czasu.
    • Operacje odczytu i zapisu danych typów prostych (primitives) pomiędzy pamięcią główną a roboczą pamięcią wątku są atomowe. Jedynym wyjątkiem mogą być operacje na 64-bitowych typach long i double, które mogą być zrealizowane jako dwie operacje 32-bitowe.
    • Reguły szeregowania
      • W każdym momencie, spośród kilku wątkow w stanie RUNNABLE wybierany jest ten o najwyższym priorytecie
      • Wykonywany wątek może być wywłaszczony, jeśli pojawi się wątek o wyższym priorytecie, gotowy do wykonania
      • Jeśli wiele wątków ma ten sam priorytet, wybierany jest jeden z nich, wg kolejności (round-robin)
      • Na niektórych systemach może być zaimplementowany podział czasu (wątki sa wywłaszczane po upływie kwantu czasu)

Wyścig

  1. Więcej niż jeden wątek korzysta jednocześnie z zasobu dzielonego, przy czym co najmniej jeden próbuje go zmienić
  2. Przyczyna niedeterministycznego zachowania się programu
  3. Może prowadzić do trudnych do wykrycia błędów
  4. Pojęcie thread-safety (bezpieczeństwo dla wątków, wielobieżność)

Ćwiczenie

  1. Proszę zaimplementować klasę Counter oraz 2 wątki: inkrementujący i dekrementujący współdzielony licznik. (2 pkt)
  2. Proszę przetestować działanie programu (czas, wynik) na różnych systemach operacyjnych oraz wersjach JVM, z brakiem oraz z użyciem synchronizacji (słowo kluczowe synchronized). (4 pkt)
  3. Prosze użyć klas z pakietu java.util.concurrent.atomic - zoptymalizowane w celu zmniejszenia narzutu. (2 pkt)
  4. Proszę sprawdzić ile wątków da się utworzyć w systemie.

Bibliografia

  1. Jacek Rumiński, Język Java. Rozdział o wątkach
  2. Bill Venners, Inside the Java Virtual Machine (rozdz. 5, rozdz. 20), McGraw-Hill Companies; 2nd Bk&Cdr edition, 2000.
  3. Bartosz Baliś, Teoria Współbieżności, materiały własne


Maciej Malawski, malawski at agh.edu.pl