并发编程工具类 ---- CountDownLatch 与 CyclicBarrier 的用法与区别

CountDownLatch

作用:

是一组线程等待其他的线程完成工作以后在执行,加强版join。await用来等待,countDown负责计数器的减 1.

代码演示:

package com.jym.thread;

import java.util.concurrent.CountDownLatch;

/**
 * @program: jym-concurrent
 * @description: 定义一个阈值为6的 CountDownLatch ,启动5个线程来 countdown,来开启业务线程的运行.
 * @author: jym
 * @create: 2020/06/02
 */
public class UseCountLatch {

    // 定义一个阈值为6的 CountDownLatch
    private static CountDownLatch countDownLatch  = new CountDownLatch(6);

    // 启动线程.
    public static class countDownThread implements Runnable {

        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName() + " : " + "I am countDown Thread!!");
            countDownLatch.countDown();
        }
    }

    // 业务线程
    public static class bussThread implements Runnable {

        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName() + " : " + "I am bussThread....");
            try {
                countDownLatch.await();
            } catch (Exception e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + " : " + "I am working..........");
        }
    }


    public static void main(String[] args) {
        new Thread(new bussThread()).start();
        // 启动一个线程 countDown 两次
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("I am Thread, countDown one... ");
                countDownLatch.countDown();
                System.out.println("I am Thread, countDown two... ");
                countDownLatch.countDown();
            }
        });
        thread.start();

        // 启动三个启动线程
        for (int i = 0; i < 3; i++ ) {
            new Thread(new countDownThread()).start();
        }
        // 主线程 countDown 一次。
        countDownLatch.countDown();

    }


}
说明:
  1. 并不是一个线程只能 countDown 一次,可以 countDown 多次。而且不是阻塞方法。
  2. countDown 的线程可以小于等于 countDownLatch的阈值。
  3. 业务线程需要外部的线程通过 countDown 去唤醒。

CyclicBarrier

作用

让一组线程达到某个屏障,被阻塞,一直到组内最后一个线程达到屏障时,屏障开放,所有被阻塞的线程会继续运行CyclicBarrier(int parties)。

CyclicBarrier(int parties, Runnable barrierAction),屏障开放,barrierAction定义的任务会执行。

代码演示
package com.jym.thread;

import java.util.concurrent.CyclicBarrier;

/**
 * @program: jym-concurrent
 * @description: 定义一个阈值为 5 的屏障,当屏障打开时,5个线程同时运行。
 * @author: jym
 * @create: 2020/06/02
 */
public class UseCyclicBarrier {

    private static CyclicBarrier cyclicBarrier = new CyclicBarrier(5);

    public static class workerThread implements Runnable {

        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName() + ": " + "I am await...");
            try {
                cyclicBarrier.await();
            } catch (Exception e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + ": " + "I am working...");
        }
    }

    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {
            new Thread(new workerThread()).start();
        }
    }

}
说明:
  1. 等待线程必须等于 cyclicBarrier 的阈值。
  2. 等待线程的运行是通过内部线程去唤醒。

CountDownLatch和CyclicBarrier辨析

  • countdownlatch放行由第三者控制,CyclicBarrier放行由一组线程本身控制。
  • countdownlatch放行条件》=线程数,CyclicBarrier放行条件=线程数。

你可能感兴趣的:(多线程)