让多个线程等待就绪之后一起执行

田径运动员在赛道上准备就绪,只等哨声一响就起跑,如果用多线程模拟这种情形呢?我们可以定义10个线程,然后我们用CyclicBarrier来让这10个启动的线程进入等待就绪的状态,一旦这10个线程准备就绪,就可以让这10个线程跑起来。

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class CyclicBarrierExample {
    private static class Task implements Runnable {

        private CyclicBarrier barrier;

        public Task(CyclicBarrier barrier) {
            this.barrier = barrier;
        }

        @Override
        public void run() {
            try {
                System.out.println(Thread.currentThread().getName() + " 准备就绪");
                barrier.await();
                System.out.println(Thread.currentThread().getName() + " 起跑");
            } catch (InterruptedException ex) {
            } catch (BrokenBarrierException ex) {
            }
        }
    }

    public static void main(String args[]) {

        final CyclicBarrier cb = new CyclicBarrier(10, new Runnable(){
            @Override
            public void run(){
                //一旦所有线程准备就绪,这个动作就执行
                System.out.println("准备就绪,开始!");
            }
        });

        for(int i = 1;i<=10;i++) {
                Thread  sporter= new Thread(new Task(cb) ,i+"号赛道");
                sporter.start();
        }

    }

}

结果是

2号赛道 准备就绪
4号赛道 准备就绪
3号赛道 准备就绪
1号赛道 准备就绪
5号赛道 准备就绪
6号赛道 准备就绪
7号赛道 准备就绪
8号赛道 准备就绪
9号赛道 准备就绪
10号赛道 准备就绪
准备就绪,开始!
10号赛道 起跑
2号赛道 起跑
4号赛道 起跑
1号赛道 起跑
3号赛道 起跑
6号赛道 起跑
5号赛道 起跑
9号赛道 起跑
8号赛道 起跑
7号赛道 起跑

我们也可以利用CountDownLatch来实现类似的功能,只不够这个CountDownLatch不能像CyclicBarrier可以重复利用。

import java.util.concurrent.CountDownLatch;

public class CountDownLatchDemo {

    public static void main(String args[]) {
           final CountDownLatch latch = new CountDownLatch(10);

           for(int i = 1;i<=10;i++) {
                  Thread t = new Thread(new Sport("sproter"+i, i*1000, latch));
                  t.start();
           }


           try{
                latch.await();  //会一直等到所有线程就绪
                System.out.println("所有都已准备好,可以跑了");
           }catch(InterruptedException ie){
               ie.printStackTrace();
           }

        }

    }

    class Sport implements Runnable{
        private final String name;
        private final int timeToStart;
        private final CountDownLatch latch;

        public Sport(String name, int timeToStart, CountDownLatch latch){
            this.name = name;
            this.timeToStart = timeToStart;
            this.latch = latch;
        }

        @Override
        public void run() {
            try {
                Thread.sleep(timeToStart);
            } catch (InterruptedException ex) {
            }
            System.out.println( name + " 已准备好");
            latch.countDown(); //每次减去1
        }
}

结果

sproter1 已准备好
sproter2 已准备好
sproter3 已准备好
sproter4 已准备好
sproter5 已准备好
sproter6 已准备好
sproter7 已准备好
sproter8 已准备好
sproter9 已准备好
sproter10 已准备好
所有都已准备好,可以跑了

你可能感兴趣的:(java多线程编程)