Java高并发程序设计(四)--CountDownLatch和CyclicBarrier

CountDownLatch和CyclicBarrier都是用来线程协作的。

先看CountDownLatch,它的常用方法有countDown()和await()。

当CountDownLatch初始化时,获取一个int参数,每次调用countDown()时,初始的int减1。await()后面的代码只有当int=0时才会执行。

下面是一个小例子:

public class threadDemo implements Runnable{
    static final CountDownLatch cdl=new CountDownLatch(10);
    public static int i=0;
    public static void main(String[] args) throws InterruptedException
    {
        threadDemo t=new threadDemo();
        for(int i=0;i<10;i++)
        {
            new Thread(t).start();
        }
        cdl.await();
        System.out.println(System.currentTimeMillis());
        System.out.println("over!!!");
    }

    public void run() {
        i++;
        try {
            Thread.sleep(i*1000);
            System.out.println(System.currentTimeMillis());
            cdl.countDown();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        }
}

 

我们能看到结果,await之后的内容是到十次countdown之后才被执行。

 

CyclicBarrier和CountDownLatch有些类似,不过更加强大复杂。

CountDownLatch用await()将程序分成了两段,而CyclicBarrier可以用await()将程序分成任意多段,同样CyclicBarrier也有一个初始的int,每个线程的程序段执行之后减一,归零时循环,说起来可能有些不懂,看代码就行了,示例如下:

public class threadDemo implements Runnable{
    static final CyclicBarrier cb=new CyclicBarrier(10);
    public static void main(String[] args) throws InterruptedException
    {
        threadDemo t=new threadDemo();
        for(int i=0;i<10;i++)
        {
            new Thread(t).start();
        }
    }

    public void run() {
        System.out.println("11111111");
        try {
            cb.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (BrokenBarrierException e) {
            e.printStackTrace();
        }
        System.out.println("22222222");
        try {
            cb.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (BrokenBarrierException e) {
            e.printStackTrace();
        }
        System.out.println("33333333");
        }
}

 先把await注释掉,结果如下:

去掉注释,结果如下:

程序会将划分的程序段全部执行之后再进入下一段程序。

 上面的内容只是大概。要了解更为详细的内容可以自己看相关API。

posted @ 2018-07-31 16:06  蒋曾  阅读(114)  评论(0编辑  收藏  举报