多线程之倒计时器CountDownLatch和循环栅栏CyclicBarrier

1、倒计时器CountDownLatch
CountDownLatch是一个多线程控制工具类。通常用来控制线程等待,它可以让一个线程一直等待知道计时结束才开始执行
构造函数:
public CountDownLatch(int count) //count 计数个数

例如:在主线程中启动10个子线程去数据库中获取分页数据,需要等到所有线程数据都返回之后统一做统计处理

public class CountDownLatchDemo implements Runnable{
private static final CountDownLatch end = new CountDownLatch(10);
@Override
public void run() {
System.out.println("线程名称:" + Thread.currentThread().getName());
//数据业务处理
end.countDown();//计数减1
}

public static void main(String[] args) {
    CountDownLatchDemo countDownLatchDemo = new CountDownLatchDemo();
    System.out.println("计数开始");
    for (int i = 0; i < 10; i++) {
        new Thread(countDownLatchDemo).start();
    }
    try {
        end.await();
        System.out.println("计数结束");
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

}

上述代码使用CountDownLatch的await()方法,要求主线程等待所有10个计数任务全部完成后,主线程才开始继续执行
可以通过getCount()方法获取当前的计数个数,当计数结束时count为0,且不会被重置

2、循环栅栏CyclicBarrier
CyclicBarrier也是一种多线程并发控制的工具。相比CountDownLatch,CyclicBarrier功能更加强大,主要表现在:
1)构造方法:
public CyclicBarrier(int parties, Runnable barrierAction)
CyclicBarrier的构造方法可以传入一个Runnable的barrierAction,可用于线程集结完毕后做一件特定的事情
2)CyclicBarrier可以重复使用,当一批线程凑满parties个是,计数器会归零,重新开始计数

public class CyclicBarrierDemo {

class Soldier implements Runnable{
    private CyclicBarrier cyclicBarrier;
    public Soldier(CyclicBarrier cyclicBarrier){
        this.cyclicBarrier = cyclicBarrier;
    }

    @Override
    public void run() {
        System.out.println("士兵 " + Thread.currentThread().getId() + " 报道");
        try {
            //等待所有士兵到齐
            cyclicBarrier.await();
            //执行任务
            doWork();
            cyclicBarrier.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (BrokenBarrierException e) {
            e.printStackTrace();
        }
    }

    private void doWork() throws InterruptedException {
        Thread.sleep(1000);
        System.out.println("士兵" + Thread.currentThread().getId()+ " 任务完成");
    }
}

class Commond implements Runnable{
    @Override
    public void run() {
        System.out.println("任务结束");
    }
}

public static void main(String[] args) {
    CyclicBarrierDemo cyclicBarrierDemo = new CyclicBarrierDemo();
    CyclicBarrier cyclicBarrier = new CyclicBarrier(5, cyclicBarrierDemo.new Commond());
    for (int i = 0; i < 20; i++) {
        new Thread(cyclicBarrierDemo.new Soldier(cyclicBarrier)).start();
    }

}

}

执行结果:

可以看到,线程被分成了5个一组

posted @ 2017-12-19 12:31  SheaChen  阅读(574)  评论(0编辑  收藏  举报