CountDownLatch、CyclicBarrier、Semaphore的使用

CountDownLatch(计数器)

主线程等待另外三个线程执行完成后再执行

public static void main(String[] args) {
    //定义一个CountDownLatch
    CountDownLatch countDownLatch = new CountDownLatch(3);
    // 主线程等待另外三个线程执行完成后再执行
    new Thread(() -> {
        try {
            System.out.println("开始执行01");
            Thread.sleep(3000);
            System.out.println("执行完成01");
            countDownLatch.countDown();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }).start();

    new Thread(() -> {
        try {
            System.out.println("开始执行02");
            Thread.sleep(3000);
            System.out.println("执行完成02");
            countDownLatch.countDown();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }).start();

    new Thread(() -> {
        try {
            System.out.println("开始执行03");
            Thread.sleep(3000);
            System.out.println("执行完成03");
            countDownLatch.countDown();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }).start();

    try {
        System.out.println("等待3个线程执行完毕。。。");
        countDownLatch.await();
        System.out.println("主线程开始执行");
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

 

CyclicBarrier(回环栅栏)

三个线程互相等待await执行完成后继续执行

public static void main(String[] args) {
    CyclicBarrier cyclicBarrier = new CyclicBarrier(3);

    // 三个线程互相等待await执行完成后继续执行
    new Thread(() -> {
        try {
            System.out.println("开始执行01");
            Thread.sleep(3000);
            System.out.println("执行完成01");
            cyclicBarrier.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (BrokenBarrierException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"所有线程执行完毕,继续处理其他任务...");
    }).start();

    new Thread(() -> {
        try {
            System.out.println("开始执行02");
            Thread.sleep(3000);
            System.out.println("执行完成02");
            cyclicBarrier.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (BrokenBarrierException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"所有线程执行完毕,继续处理其他任务...");
    }).start();

    new Thread(() -> {
        try {
            System.out.println("开始执行03");
            Thread.sleep(3000);
            System.out.println("执行完成03");
            cyclicBarrier.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (BrokenBarrierException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"所有线程执行完毕,继续处理其他任务...");
    }).start();

}

 

Semaphore(信号量)

8个工人使用5台机器

public class Test {
    public static void main(String[] args) {
        int N = 8;            //工人数
        Semaphore semaphore = new Semaphore(5); //机器数目
        for(int i=0;i<N;i++)
            new Worker(i,semaphore).start();
    }

    static class Worker extends Thread{
        private int num;
        private Semaphore semaphore;
        public Worker(int num,Semaphore semaphore){
            this.num = num;
            this.semaphore = semaphore;
        }

        @Override
        public void run() {
            try {
                semaphore.acquire();
                System.out.println("工人"+this.num+"占用一个机器在生产...");
                Thread.sleep(2000);
                System.out.println("工人"+this.num+"释放出机器");
                semaphore.release();           
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

 

总结

  • CountDownLatch用作某个线程等待其他的线程执行完成后,它才执行。
  • CyclicBarrier用作一组线程等待到某个状态,然后这组线程才继续执行。
  • CountDownLatch是不能够重用的,而CyclicBarrier是可以重用的。
  • Semaphore类似于锁,对资源访问权限控制。
posted @ 2020-01-10 14:15  阿尔伯特爱因斯坦  阅读(224)  评论(0编辑  收藏  举报