2

我已经阅读了 Bloch 的 Item 69(Effective Java) 并且有一个用于定时执行的简单框架的示例,它使用 3 个CountDownLatch同步线程。Bloch 还说这个例子可以用 1 重写CyclicBarrier。我试图这样做并获得下一个代码:

     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");
        }

    }

但我认为这里有一个问题(在time方法中):首先await我尝试测量线程执行的开始时间,所以我想在所有其他线程开始之前测量这个时间。没有任何保证 this( long time = System.nanoTime();) 指令会在另一个线程启动之前执行。

如何使用 CyclicBarrier 实现这样的功能?有什么建议么?

4

1 回答 1

3

CyclicBarrier允许您定义要在所有线程到达屏障之后但在它们恢复执行之前执行的屏障操作。用来CyclicBarrier(int, Runnable)定义它。

显然,在您的情况下,您可以在工作之前和完成之后区分屏障动作的执行,如下所示:

class TimingAction implements Runnable {
    private boolean running;
    private long start;
    private long elapsed;

    public void run() {
        if (running) {
            elapsed = System.nanoTime() - start;
            running = false;
        } else {
            start = System.nanoTime();
            running = true;
        }
    }
    ...
}

TimingAction timer = new TimingAction();
CyclicBarrier cyclicBarrier = new CyclicBarrier(count + 1, timer);
...
long elapsed = timer.getElapsed();
于 2012-09-13T08:28:51.257 回答