2

CountDownLatchBloch の Item 69(Effective Java) を読みましたが、同期スレッドに3 を使用するタイミング実行用のシンプルなフレームワークの例がありました。また、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にスレッドの実行開始時間を測定しようとした後、他のすべてのスレッドが開始する前にこの時間を測定したいと思います。long time = System.nanoTime();this( ) 命令が別のスレッドの開始前に実行されるという保証はありません。

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 に答える