Countdownlatch与CyclicBarrier

CountDownLatch : 一个线程(或者多个), 等待另外N个线程完成某个事情之后才能执行。 CyclicBarrier : N个线程相互等待,任何一个线程完成之前,所有的线程都必须等待。
这样应该就清楚一点了,对于CountDownLatch来说,重点是那个“一个线程”, 是它在等待, 而另外那N的线程在把“某个事情”做完之后可以继续等待,可以终止。而对于CyclicBarrier来说,重点是那N个线程,他们之间任何一个没有完成,所有的线程都必须等待。

CountDownLatch:

package com.guozz.test.testCountDownLatchAndCyclicBarrier;
 
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
 
/**
 * 
 * @author paul
 * 
 * CountDownLatch 很适合用来将一个任务分为n个独立的部分,等这些部分都完成后继续接下来的任务,
 * CountDownLatch 只能出发一次,计数值不能被重置。
 * 
 * 基于CountDownLatch 的模拟项目,一个项目可以分为多个模块,只有但这些模块都完成后才可以继续下一步的工作。
 * 
 * 
 *  countDown方法,当前线程调用此方法,则计数减一
    await方法,调用此方法会一直阻塞当前线程,直到计时器的值为0
    
    executorService.shutdown() 并不是终止线程的运行,而是禁止在这个Executor中添加新的任务
     void shutdown()
        启动一个关闭命令,不再接受新任务,当所有已提交任务执行完后,就关闭。如果已经关闭,则调用没有其他作用。
        抛出:
        SecurityException - 如果安全管理器存在并且关闭,此 ExecutorService 可能操作某些不允许调用者修改的线程
                       (因为它没有保持 RuntimePermission("modifyThread")),或者安全管理器的 checkAccess 方法拒绝访问。
 */
public class CountDownLatchTest {
    //定义计数器
    static  final int  SIZE=20;
    
    public static void main(String[] args) {
        CountDownLatch latch = new CountDownLatch(SIZE);
        Random random = new Random();
        ExecutorService executorService = Executors.newCachedThreadPool();
        //让等待所有子线程执行完毕
        Controller controller = new Controller(latch);
        executorService.execute(controller);
        
        //将SIZE个小任务去执行,多个子线程任务
        for(int i=0;i

CyclicBarrier

package com.guozz.test.testCountDownLatchAndCyclicBarrier;
 
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
 
/**
 * 
 * @author HardPass
 * 
 * CyclicBarrier:一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。
 *  在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 CyclicBarrier 很有用。
 * 因为该 barrier 在释放等待线程后可以重用,所以称它为循环 的 barrier。
    CyclicBarrier可以多次重复使用
 */
public class CyclicBarrierTest_RelayRace {
 
    public static void main(String[] args) throws InterruptedException {
        
        ExecutorService exec = Executors.newCachedThreadPool();
        
        final CyclicBarrier barrier = new CyclicBarrier(4, new Runnable() {
 
            @Override
            public void run() {
                System.out.println("好了,大家可以去吃饭了……"  );
            }
        });     
        
        System.out.println("要吃饭,必须所有人都到终点,oK?");                
        System.out.println("不放弃不抛弃!");
        
        for (int i = 0; i < 4; i++) {
            exec.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName() + ":Go");
                    try {
                        Thread.sleep((long) (2000 * Math.random()));
                    } catch (InterruptedException e1) {
                        e1.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName()+ ":我到终点了");
                    try {
                        barrier.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } catch (BrokenBarrierException e) {
                        e.printStackTrace();
                    }
                    
                    System.out.println(Thread.currentThread().getName()+ ":终于可以吃饭啦!");
 
                }
            });
 
        }
        exec.shutdown();
                
    }
    
    
 
}
 

你可能感兴趣的:(Countdownlatch与CyclicBarrier)