CyclicBarrier和CountDownLatch笔记

一、CyclicBarrier的使用

  Barrier是栅栏,障碍物的意思,这里将它理解为栅栏。

  Cyclic是重复利用的意思。

  CyclicBarrier:可重复利用的栅栏。这里附上官方文档的一句解释:The barrier is called<em>cyclic</em> because it can be re-used after the waiting threads are released.

  大概意思是等待的线程被释放以后就可以重新使用这个栅栏。

  

  栅栏的使用条件:它必须使用在线程类中。也就是说你可以把CyclicBarrier作为线程类的一个变量。

  在代码中插入一个栅栏,当代码执行到栅栏处就被拦截住了,不能继续往下执行。一直等到所有的线程都执行到栅栏处,才可以继续执行。

    public static void main(String[] args)
    {
        CyclicBarrier barrier = new CyclicBarrier(10);//设置你要拦截的线程的个数。
        
        for(int i = 0; i < 10; i++)
        {
            new Thread(new Worker(barrier)).start();
            System.out.println("第" + i + "个线程已经启动");
            
        }
    }

线程类中持有CyclicBarrier的引用。

class Worker implements Runnable
{
    private CyclicBarrier barrier;
    
    public Worker(CyclicBarrier barrier)
    {
        this.barrier = barrier;
    }
    
    @Override
    public void run()
    {
        try
        {
            Thread.sleep((long)(Math.random() * 10000));
        } catch (InterruptedException e)
        {
            e.printStackTrace();
        }
        
        try
        {
            System.out.println("代码....");
            barrier.await();//栅栏,栅栏的启用就是调用await()方法就行了。还可以调用它的重载方法await(long timeout, TimeUnit unit)
            System.out.println("代码.....");
        } catch (InterruptedException e)
        {
            e.printStackTrace();
        } catch (BrokenBarrierException e)
        {
            e.printStackTrace();
        }
        
        System.out.println("你好");
    }
}

 

二、CountDownLatch

  感觉CountDownLatch和CyclicBarrier有点相似,所以就记在一起。

  说一下两者的区别,CyclicBarrier的作用是让多个线程都执行到栅栏的时候,这写线程再继续执行,比如,有十个线程,要全部等到这十个线程都到栅栏以后,再各自前进。而CountDownLatch则是用来让多个线程都执行完以后再继续往下执行。比如,在一个主线程中创建了10个线程并启动运行它们。本来的是这十个线程启动完后主线程就可以继续往下执行了,但是现在需要等这十个线程执行完毕以后(更准确的说应该是getCount()的返回值为0的时候)主线程才能往下执行。那么这时候就需要CountDownLatch来完成。

例子:

public class CountDownLatchTest
{
    public static void main(String[] args)
    {
        CountDownLatch countDownLatch = new CountDownLatch(5);
        
        for(int i = 0; i < 10; i++)
        {
            new Thread(new CountDownRun(countDownLatch, i)).start();
        }
        
        //需要等到10个线程都执行完以后才能继续往下执行。准确的来说应该是计数器不断减一,当减到0的时候主线程就可以继续往下执行了。
        try
        {
            countDownLatch.await();
        } catch (InterruptedException e)
        {
            e.printStackTrace();
        }
        
        System.out.println("await()之后继续执行");
    }
}

 

class CountDownRun implements Runnable
{
    private CountDownLatch countDownLatch;//线程持有同一个countDownLatch
    private int i;
    
    public CountDownRun(CountDownLatch countDownLatch, int i)
    {
        this.countDownLatch = countDownLatch;
        this.i = i;
    }
    
    @Override
    public void run()
    {
        System.out.println("你好!" + i);
        
        try
        {
            Thread.sleep((long)(Math.random() * 1000));
        } catch (InterruptedException e)
        {
            e.printStackTrace();
        }
        System.out.println("睡醒了。。。" + i);
        countDownLatch.countDown();//减一
        System.out.println("减一后");
    }
}

 三、CountDownLatch还有一种用法,参见类注释。

posted @ 2017-12-31 02:28  钓鱼翁  阅读(229)  评论(0编辑  收藏  举报