CountDownLatch 跟 CyclicBarrier 的区别

CountDownLatch 和 CyclicBarrier 的区别

CountDownLatch只能使用一次

CyclicBarrier:        可以循环使用

 

 

package com.colorcc.multi.thread.jcp;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CountDownLatchDemo {
    private static CountDownLatch cdl = new CountDownLatch(3);

    public static void main(String[] args) throws InterruptedException {

        ExecutorService executor = Executors.newFixedThreadPool(3);
        for (int i = 0; i < 3; i++) {
            executor.execute(new CountDownLatchThread());
        }
        System.out.println("Main start ...");
        cdl.await();
        System.out.println("Main after ..."); // main 的语句永远比线程的晚

    }

    static class CountDownLatchThread implements Runnable {

        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName() + " start ...");
            System.out.println(Thread.currentThread().getName() + " after ...");
            cdl.countDown();
            // cdl.countDown(); // 这里算再减一次
        }

    }

}

 

某次执行结果:

pool-1-thread-1 start ...
pool-1-thread-1 after ...
pool-1-thread-2 start ...
pool-1-thread-2 after ...
Main start ...
pool-1-thread-3 start ...
pool-1-thread-3 after ...
Main after ...  //必然在最后

 

 

package com.colorcc.multi.thread.jcp;

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

public class CyclicBarrierDemo {

    /**
     * @param args
     */
    public static void main(String[] args) {
        final CyclicBarrier cb = new CyclicBarrier(3, new Runnable() {
            //每次 await() 后调用此方法
            @Override
            public void run() {
               
                System.out.println("Succeed.");
            }

        });

        ExecutorService executor = Executors.newFixedThreadPool(3);
        for (int i = 0; i < 3; i++) {
            executor.execute(new Runnable() {

                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName() + " before.");
//                    try {
//                        Thread.sleep(200);
//                    } catch (InterruptedException e1) {
//                        e1.printStackTrace();
//                    }
                    System.out.println(Thread.currentThread().getName() + " after sleep.");
                    try {
                        cb.await(); //等待点1: 所有线程执行到此,等待别人都执行完成,继续向下
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } catch (BrokenBarrierException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + " middle.");
                    try {
                        cb.await(); //等待点2: 所有线程执行到此,再次等待别人都执行完成,继续向下
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } catch (BrokenBarrierException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + " after.");
                    try {
                        cb.await(); //等待点3: 所有线程执行到此,再次等待别人都执行完成,继续向下
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } catch (BrokenBarrierException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + " last.");
                }
            });
        }
       
        System.out.println("Main done.");

    }

}

某次执行结果:

pool-1-thread-1 before.   //可以无序
pool-1-thread-2 before.

pool-1-thread-2 after sleep.
pool-1-thread-3 before.
pool-1-thread-3 after sleep.
Main done.
pool-1-thread-1 after sleep.
Succeed.
pool-1-thread-1 middle.   //等待点1后
pool-1-thread-2 middle.
pool-1-thread-3 middle.
Succeed.
pool-1-thread-3 after. //等待点2后
pool-1-thread-2 after.
pool-1-thread-1 after.
Succeed.
pool-1-thread-1 last. //等待点3后
pool-1-thread-3 last.
pool-1-thread-2 last.