diff --git a/src/main/java/_11/_2/alternative/Barriers.java b/src/main/java/_11/_2/alternative/Barriers.java new file mode 100644 index 0000000..03f81f4 --- /dev/null +++ b/src/main/java/_11/_2/alternative/Barriers.java @@ -0,0 +1,16 @@ +package _11._2.alternative; + +public class Barriers { + + public static final int NUMBER_OF_RUNNERS = 3; + + public static void main(String[] args) { + NumberRunner[] runners = new NumberRunner[NUMBER_OF_RUNNERS]; + for(int i = 0; i < NUMBER_OF_RUNNERS; i++) { + runners[i] = new NumberRunner(i); + } + for(int i = 0; i < NUMBER_OF_RUNNERS; i++) { + runners[i].start(); + } + } +} diff --git a/src/main/java/_11/_2/alternative/Checkpoint.java b/src/main/java/_11/_2/alternative/Checkpoint.java new file mode 100644 index 0000000..c8e3f25 --- /dev/null +++ b/src/main/java/_11/_2/alternative/Checkpoint.java @@ -0,0 +1,31 @@ +package _11._2.alternative; + +import java.util.concurrent.atomic.AtomicInteger; + +public class Checkpoint { + + private static AtomicInteger GATHERED = new AtomicInteger(0); + + private final Object lock = new Object(); + private int groupSize; + + public Checkpoint(int groupSize) { + this.groupSize = groupSize; + } + + /** + * Blocks until called by {@link #groupSize} different Threads, + * then wakes all of them up again. + */ + public void gather() throws InterruptedException { + synchronized(this.lock) { + if(GATHERED.incrementAndGet() != this.groupSize) { + this.lock.wait(); + } else { + GATHERED.set(0); + System.out.println("Group gathered"); + this.lock.notifyAll(); + } + } + } +} \ No newline at end of file diff --git a/src/main/java/_11/_2/alternative/NumberRunner.java b/src/main/java/_11/_2/alternative/NumberRunner.java new file mode 100644 index 0000000..a9017e1 --- /dev/null +++ b/src/main/java/_11/_2/alternative/NumberRunner.java @@ -0,0 +1,27 @@ +package _11._2.alternative; + +public class NumberRunner extends Thread { + + private static final Checkpoint CHECKPOINT = new Checkpoint(Barriers.NUMBER_OF_RUNNERS); + + private final int id; + + public NumberRunner(int id) { + this.id = id; + } + + @Override + public void run() { + for(int i = 0; i < 1000; i++) { + if(i % 10 == 0) { + try { + CHECKPOINT.gather(); + } catch(InterruptedException e) { + throw new IllegalStateException("Group can never be complete again, because one of the members got lost", e); + } + } + + System.out.println("Thread " + this.id + ": " + i); + } + } +}