Spis treści

Demo 1 (20-25 min): Wyścig danych i poprawki

Cel: pokazać, że brak synchronizacji daje błędne wyniki.

Kroki:

Szkielet:

int threads = 8;
int increments = 100_000;
 
// uruchomienie wielu wątków i join
// wypisanie: expected = threads * increments

Demo 1 - wskazówki i rozwiązanie

Wskazówki:

Wersja poprawna (AtomicInteger):

import java.util.concurrent.atomic.AtomicInteger;
 
class AtomicCounter {
    private final AtomicInteger value = new AtomicInteger();
    void inc() { value.incrementAndGet(); }
    int get() { return value.get(); }
}

Demo 2 (20-25 min): Producent-konsument

Cel: komunikacja wait/notifyAll na monitorze.

Zakres:

Wskazówki:

Demo 2 - rozwiązanie (skrót)

OneSlotBuffer buffer = new OneSlotBuffer();
 
Thread producer = new Thread(() -> {
    for (int i = 1; i <= 10; i++) {
        try { buffer.put(i); } catch (InterruptedException e) { Thread.currentThread().interrupt(); }
    }
});
 
Thread consumer = new Thread(() -> {
    for (int i = 1; i <= 10; i++) {
        try { System.out.println(buffer.take()); } catch (InterruptedException e) { Thread.currentThread().interrupt(); }
    }
});
 
producer.start();
consumer.start();

Zadania samodzielne (20-25 min) - wybór

Wybierz jedno zadanie. Każde zawiera wersję podstawową i rozszerzenie.

Zadanie A (łatwe): Licznik wielowątkowy

Wymagania:

Wskazówki:

Rozwiązanie (minimum):

// expected = 300_000
// brokenCounter -> zwykle mniej
// fixedCounter  -> dokładnie 300_000

Zadanie B (średnie): Suma tablicy w wielu wątkach

Wymagania:

Wskazówki:

Rozwiązanie (minimum):

// podziel [0, n) na k przedziałów
// submit Callable<Long>
// sumuj wyniki z Future.get()

Zadanie C (trudniejsze): Ograniczony downloader

Wymagania:

Wskazówki:

Rozwiązanie (minimum):

ExecutorService pool = Executors.newFixedThreadPool(3);
for (String file : files) {
    pool.submit(() -> {
        System.out.println("START " + file + " " + Thread.currentThread().getName());
        Thread.sleep(500);
        System.out.println("END   " + file + " " + Thread.currentThread().getName());
    });
}
pool.shutdown();

Zadanie D (dla chętnych): Deadlock i naprawa

Wymagania:

Wskazówki:

Zadanie PA

Zadanie 4.1

Zaimplementuj klasę, która wykorzystując wątki pozwoli na podanie sumy wszystkich elementów w tablicach wygenerowanych losowo. Użytkownik ma mieć możliwość określenia długości tablic i ich liczby.

Zadanie 4.2

Zaimplementuj klasę statyczną, która z wykorzystaniem wielu wątków pozwoli wykonywanie mnożenia dwóch macierzy przechowywanych w postaci tablic dwuwymiarowych. Zadbaj o to, aby przed rozpoczęciem operacji sprawdzić, czy mnożenie macierzy można w ogóle wykonać.

Zadanie 4.3

Zaimplementuj klasę statyczną, która pozwoli z wykorzystaniem wielu wątków doprowadzić macierz przechowywaną w postaci tablicy dwuwymiarowej do postaci górnotrójkątnej (eliminacja Gaussa). Dodatkowe 3 pkt. otrzymać można za doprowadzenie macierzy do postaci zdiagonalizowanej. Przed wykonaniem operacji sprawdź, czy spełnione są warunki niezbędne do tego, aby operacja się powiodła.