I have read Bloch’s Item 69(Effective Java) and there was an example of Simple framework for timing execution which uses 3 CountDownLatch for synchronization threads. Also Bloch says that this example can be rewritten using 1 CyclicBarrier. I have tried to do this and get the next code:
public static long time(ExecutorService exec, int count) throws InterruptedException, BrokenBarrierException {
CyclicBarrier cyclicBarrier = new CyclicBarrier(count+1);
for (int i = 0; i < count; i++) {
exec.submit(new Worker(cyclicBarrier, i));
}
System.out.println("Start processing");
cyclicBarrier.await();
long time = System.nanoTime();
cyclicBarrier.await();
long elapsedTime = (System.nanoTime() - time)/1000;
System.out.println("FIN. ");
return elapsedTime;
}
private static class Worker implements Runnable {
final CyclicBarrier cyclicBarrier;
int workerNumber;
Worker(CyclicBarrier cyclicBarrier, int workerCount) {
this.cyclicBarrier = cyclicBarrier;
this.workerNumber = workerCount;
}
public void run() {
try {
cyclicBarrier.await();
work();
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
private void work() {
System.out.println("Worker " + workerNumber + " starts his job");
System.out.println("Worker " + workerNumber + " finishes his job");
}
}
But I think there is a problem here(in time method): after first await I try to measure time of start of threads’ execution, so I want to measure this time BEFORE all another threads starts. There is no any guarantee that this(long time = System.nanoTime();) instruction will execute before another threads start.
How can I achieve such functionality with CyclicBarrier? Any suggestions?
CyclicBarrierallows you to define a barrier action to be executed after all threads reached the barrier but before they resumed execution. UseCyclicBarrier(int, Runnable)to define it.Obviously, in your case it’s up to you to distinguish between executions of barrier action before doing work and after finishing it, something like this: