pp.06.02-LockTiming

Vergleich von ReentrantLock, ReentrantReadWriteLock, StampedLock und synchronized

  • Projekt: pp.06.02-LockTiming
  • Bearbeitungszeit: 30 Minuten
  • Musterlösung: 20 Minuten
  • Kompatibilität: mindestens Java SE 10

Quellcode von pp.Experiment

package pp;

public abstract class Experiment {
  static final int WRITES = 1; // 5000
  static final int READS = 9999; // 5000
  static final int TRIALS = 100000000 / (WRITES + READS);

  protected int counter;

  public void experimentSingle() {
    for (var i = 0; i < TRIALS; i++) {
      for (var j = 0; j < WRITES; j++) {
        incCounter();
      }
      for (var j = 0; j < READS; j++) {
        getCounter();
      }
    }
  }

  public void experimentPar() throws InterruptedException {
    var t1 = new Thread(() -> experimentSingle());
    var t2 = new Thread(() -> experimentSingle());
    var now = System.currentTimeMillis();
    t1.start();
    t2.start();
    t1.join();
    t2.join();
    System.out
        .printf("Lauf %s, Zeitdauer: %dms",
            (getCounter() - (2 * TRIALS * WRITES)) == 0 ? "korrekt"
                : "fehlerhaft",
            System.currentTimeMillis() - now);
  }

  public abstract void incCounter();

  public abstract int getCounter();

}

Quellcode von pp.ExpUnsynchronized

package pp;

public class ExpUnsynchronized extends Experiment {

    @Override
    public void incCounter() {
        this.counter++;
    }

    @Override
    public int getCounter() {
        return this.counter;
    }

    public static void main(String... args) throws InterruptedException {
        (new ExpUnsynchronized()).experimentPar();
    }
}

Aufgaben

  • Bilden Sie von der abstrakten Klasse Experiment Unterklassen namens ExpSynchronized, ExpReentrantLock, ExpReadWriteLock und ExpStampedLock. Überschreiben Sie die abstrakten Methoden…
public abstract void incCounter();
public abstract int getCounter();

… jeweils mit threadsicheren Implementierungen, die entweder synchronized, ReentrantLock, ReentrantReadWriteLock oder StampedLock zur Koordination des nebenläufigen Zugriffs auf die Instanzvariable counter verwenden.

  • Verwenden Sie die main-Methode wie in ExpUnsynchronized, also:
public static void main(String... args) throws InterruptedException {
    (new ExpUnsynchronized()).experimentPar();
}

… oder eine vergleichbare Funktionalität, um die Laufzeit mit zwei Threads und einem steuerbaren Verhältnis von lesenden und ändernden Zugriffen zu analysieren.

  • Führen Sie Messungen der Laufzeit durch.
  • Vergleichen Sie auch das Zeitverhalten für ReentrantLock(false) und ReentrantLock(true) sowie analog bei ReentrantReadWriteLock(false) und ReentrantReadWriteLock(true).