CyclicBarrierのサンプル

こないだのときは説明できなかったけど、CyclicBarrier
いくつかのスレッドがバリアにたどりつくまで待ちます。
このサンプルではスピードの違う「電車」がまんなかで全ての「電車」がそろうまで待ちます。


コンストラクタでいくつのスレッドを待つかを決めます。

CyclicBarrier barrier = new CyclicBarrier(10);


awaitメソッドで、ほかのスレッドがバリアにたどりつくのを待ちます。

barrier.await();


ソースはこれ

import java.awt.*;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import javax.swing.*;

public class BarrierSample{
    private static CyclicBarrier barrier = new CyclicBarrier(10);

    public static void main(String args[]) {
        JFrame f = new JFrame("Barrierサンプル");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setLayout(new GridLayout(0, 1));

        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        f.setBounds((screenSize.width-400)/2, (screenSize.height-300)/2, 400, 300);

        for(int i = 0; i < 10; ++i){
            JTextField tf = new JTextField();
            f.add(tf);
            Runner r = new Runner();
            r.tf = tf;
            new Thread(r).start();
        }
        f.setVisible(true);
    }

    private static class Runner implements Runnable{
        JTextField tf;
        int speed = (int) (Math.random() * 40 + 50);
        @Override
        public void run(){
            try {
                String tr = "電車>";
                for(int i = 0; i < 50; ++i){
                    tf.setText(tr);
                    tr = " " + tr;
                    Thread.sleep(speed);
                }
                try {
                    barrier.await(); //みんなそろうまで進めない
                } catch (BrokenBarrierException ex) {
                }
                for(int i = 0; i < 50; ++i){
                    tf.setText(tr);
                    tr = " " + tr;
                    Thread.sleep(speed);
                }
            } catch (InterruptedException ex) {
            }
        }
    }

}