多线程工具类CountDownLatch、CyclicBarrier的理解

289 阅读3分钟

在开发过程中会需要使用到多线程工具类,在此记录对CountDownLatch、CyclicBarrier的理解;

CountDownLatch

CountDownLatch是一个同步工具类,用来协调多个线程之间的同步,CountDownLatch能够使一个线程在等待另外一些线程完成各自工作之后,再继续执行。使用一个计数器进行实现。计数器初始值为线程的数量。当每一个线程完成自己任务后,计数器的值就会减一。当计数器的值为0时,表示所有的线程都已经完成一些任务,然后在CountDownLatch上等待的线程就可以恢复执行接下来的任务;

其中主要的二个方法:
    latch.countDown();  计数器减一  
    latch.await();  锁住主线程   
    
    public class ThreadTest {
    private static Integer QUERY_THREAD_SIZE=3; //核心线程数量
    private static Integer QUERY_THREAD_MAX=6;   //最大存活数
    //guava提供的ThreadFactoryBuilder  获取线程的名字
    private static ThreadFactory namedThreadFactory = new ThreadFactoryBuilder()
            .setNameFormat("thread_factory-pool-%d").build();
    
public void TestJuc() throws InterruptedException {
        //线程辅助类工具
        final CountDownLatch latch = new CountDownLatch(QUERY_THREAD_SIZE);
        //创建线程池
        ExecutorService threadPool = new ThreadPoolExecutor(QUERY_THREAD_SIZE, QUERY_THREAD_MAX,
                0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<>(1024), 
                namedThreadFactory, new ThreadPoolExecutor.AbortPolicy());
    
        System.out.println("下面开始制作满汉全席----start");
        threadPool.submit(() -> testDoSomeThing("青菜",latch));
        threadPool.submit(() -> testDoSomeThing("牛肉",latch));
        threadPool.submit(() -> testDoSomeThing("冬菇汤",latch));
        latch.await();
        System.out.println("制作结束");
    }

    public void testDoSomeThing(String s,CountDownLatch latch){
        System.out.println("这是一道" + s + "目前计数器的值为" + latch);
        System.out.println(Thread.currentThread().getName());
        latch.countDown();
    }
}

Result:
下面开始制作满汉全席----start
这是一道青菜目前计数器的值为java.util.concurrent.CountDownLatch@5d72b9a[Count = 3]
thread_factory-pool-0
这是一道牛肉目前计数器的值为java.util.concurrent.CountDownLatch@5d72b9a[Count = 2]
thread_factory-pool-1
这是一道冬菇汤目前计数器的值为java.util.concurrent.CountDownLatch@5d72b9a[Count = 1]
thread_factory-pool-2
制作结束    

CyclicBarrier

一组线程同时到达临界点后再恢复执行(先到达临界点的线程会阻塞,直到所有线程都到达临界点)
主要方法为:
    barrier.await();
    
public class ThreadTest {
    private static Integer QUERY_THREAD_SIZE=3; //核心线程数量
    private static Integer QUERY_THREAD_MAX=6;   //最大存活数
    //guava提供的ThreadFactoryBuilder  获取线程的名字
    private static ThreadFactory namedThreadFactory = new ThreadFactoryBuilder()
            .setNameFormat("thread_factory-pool-%d").build();
    @Test
    public void TestJuc() {
        //线程辅助类工具
        CyclicBarrier cyclicBarrier = new CyclicBarrier(QUERY_THREAD_SIZE);
        //创建线程池
        ExecutorService threadPool = new ThreadPoolExecutor(QUERY_THREAD_SIZE, QUERY_THREAD_MAX,
                0L, TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<>(1024), namedThreadFactory, new ThreadPoolExecutor.AbortPolicy());
        threadPool.submit(() -> {
            try {
                testDoSomeThing("青菜",cyclicBarrier);
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        threadPool.submit(() -> {
            try {
                testDoSomeThing("牛肉",cyclicBarrier);
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        threadPool.submit(() -> {
            try {
                testDoSomeThing("冬菇汤",cyclicBarrier);
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

    }

public void testDoSomeThing(String s, CyclicBarrier barrier) throws BrokenBarrierException, InterruptedException {
        System.out.println("这是一道" + s + "目前到达终点的是" + Thread.currentThread().getName());
        barrier.await();
        System.out.println(Thread.currentThread().getName() + "又开始执行了");
    }
}

result:
这是一道青菜目前到达终点的是thread_factory-pool-0
这是一道牛肉目前到达终点的是thread_factory-pool-1
这是一道冬菇汤目前到达终点的是thread_factory-pool-2
thread_factory-pool-0又开始执行了
thread_factory-pool-1又开始执行了
thread_factory-pool-2又开始执行了

鄙人不才,在您面前献丑只愿与您结伴而行,文章若有不当之处,望大佬指点一二;如果我对您有帮助的话,还希望您能点赞分享,成长是一场苦涩的独自修行,我很需要您的陪伴与支持,这也是鄙人不断前行的根本动力,让我们在互相陪伴见证彼此生长的同时能够感染身边最亲近的人一同成长,鄙人在此叩谢!