pp.06.01-SynchInterrupt

Unterbrechbarkeit von Threads, die blockiert sind

  • Projekt: pp.06.01-SynchInterrupt
  • Bearbeitungszeit: 25 Minuten
  • Musterlösung: 15 Minuten
  • Kompatibilität: mindestens Java SE 10

Quellcode von pp.Task

Task stellt einen Thread dar, der über die Methode kill abgebrochen werden kann, nachdem er gestartet wurde.

In der run-Methode befindet sich ein ca. 8.000 ms lang schlafender Abschnitt, der durch den Monitor Task.class geschützt ist. Wenn mehrere Instanzen von Task gestartet werden, werden deshalb alle bis auf einen nach Kurzem blockiert sein.

public class Task extends Thread {
    private volatile boolean stop = false;

    public Task(String name) {
        setName(name);
    }

    public void kill() {
        System.out.printf("%s: killing...\n", getName());
        this.stop = true;
        interrupt();
    }

    @Override
    public void run() {
        System.out.printf("%s: startup\n", getName());
        while (!this.stop) {
            try {
                synchronized (Task.class) {
                    System.out.printf("%s: working\n", getName());
                    Thread.sleep(8000);
                }
            } catch (InterruptedException e) {
                System.out.printf("%s: interrupted\n", getName());
            }
        }
        System.out.printf("%s: finished\n", getName());
    }

    // ...
}

In der main-Methode werden drei Instanzen von Task erzeugt und gestartet. Zuerst T1, dann nach 1.000 ms T2 und T3. Die beiden letzteren sind also aufgrund von synchronized blockiert. Sodann wird T2 (im Moment blockiert) über den Aufruf von kill abgebrochen.

var t1 = new Task("T1");
var t2 = new Task("T2");
var t3 = new Task("T3");
t1.start();
Thread.sleep(1000);
t2.start();
t3.start();
t2.kill();
t3.kill();
t1.kill();
t1.join();
t2.join();

Aufgaben

  • Untersuchen Sie das Verhalten in Bezug auf die Unterbrechbarkeit von Task (Lassen Sie das Programm laufen und interpretieren Sie dessen Ausgaben).
  • Bauen Sie die Klasse Task zur Verwendung von ReentrantLock um.
  • Untersuchen Sie das Verhalten in Bezug auf die Unterbrechbarkeit erneut. Prüfen Sie den Effekt von lockInterruptibly() im Vergleich zu lock().