CountDownLatch倒计时锁

CountDownLatch倒计时锁

1.基本概念

CountDownLatch用来进行线程同步协作,等待所有线程完成倒计时。
其中构造参数用来初始化等待计数值,await() 用来等待计数归零,countDown() 用来让计数减一.
CountDownLatch与CyclicBarrier的区别是:

  • CountDownLatch不可以重用,当任务Task都执行完毕后结束.当再执行其他任务时,需要重新创建.
  • CyclicBarrier可以重用, 任务Task执行完毕后不会结束,再执行其他任务时会继续使用当前的对象.

1.CountDownLatch基本用法

package com.concurrent.p10;

import lombok.extern.slf4j.Slf4j;
import org.junit.Test;

import java.util.concurrent.CountDownLatch;

@Slf4j(topic = "c.Test_CountDownLatch")
public class Test_CountDownLatch {
    
    

    public void sleep(long second) {
    
    
        try {
    
    
            Thread.sleep(second * 1000);
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
    }

    /**
     * CountDownLatch基本用法:
     * 等待3个子线程都countDown之后,唤醒主线程
     *
     * 09:10:01.740 [main] DEBUG c.Test_CountDownLatch - wait...
     * 09:10:01.740 [Thread-2] DEBUG c.Test_CountDownLatch - begin...
     * 09:10:01.740 [Thread-0] DEBUG c.Test_CountDownLatch - begin...
     * 09:10:01.740 [Thread-1] DEBUG c.Test_CountDownLatch - begin...
     * 09:10:03.747 [Thread-0] DEBUG c.Test_CountDownLatch - begin end...
     * 09:10:05.747 [Thread-1] DEBUG c.Test_CountDownLatch - begin end...
     * 09:10:07.747 [Thread-2] DEBUG c.Test_CountDownLatch - begin end...
     * 09:10:07.747 [main] DEBUG c.Test_CountDownLatch - wait end...
     */
    @Test
    public void test1() throws InterruptedException {
    
    
        CountDownLatch countDownLatch = new CountDownLatch(3);
        //线程1
        new Thread(() -> {
    
    
            log.debug("begin...");
            sleep(2);
            log.debug("begin end...");
            countDownLatch.countDown();
        }).start();
        //线程2
        new Thread(() -> {
    
    
            log.debug("begin...");
            sleep(4);
            log.debug("begin end...");
            countDownLatch.countDown();
        }).start();
        //线程3
        new Thread(() -> {
    
    
            log.debug("begin...");
            sleep(6);
            log.debug("begin end...");
            countDownLatch.countDown();
        }).start();
        //主线程
        log.debug("wait...");
        countDownLatch.await();
        log.debug("wait end...");
    }

}

2.CountDownLatch一般配合线程池使用

package com.concurrent.p10;

import lombok.extern.slf4j.Slf4j;
import org.junit.Test;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Slf4j(topic = "c.Test_CountDownLatch")
public class Test_CountDownLatch {
    
    

    public void sleep(long second) {
    
    
        try {
    
    
            Thread.sleep(second * 1000);
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
    }

    /**
     * CountDownLatch配合线程池使用:
     *
     * 09:18:43.493 [pool-1-thread-2] DEBUG c.Test_CountDownLatch - begin...
     * 09:18:43.493 [pool-1-thread-3] DEBUG c.Test_CountDownLatch - begin...
     * 09:18:43.493 [pool-1-thread-1] DEBUG c.Test_CountDownLatch - begin...
     * 09:18:45.498 [pool-1-thread-1] DEBUG c.Test_CountDownLatch - begin end...
     * 09:18:47.499 [pool-1-thread-2] DEBUG c.Test_CountDownLatch - begin end...
     * 09:18:49.498 [pool-1-thread-3] DEBUG c.Test_CountDownLatch - begin end...
     * 09:18:49.498 [pool-1-thread-4] DEBUG c.Test_CountDownLatch - begin...
     * 09:18:50.498 [pool-1-thread-4] DEBUG c.Test_CountDownLatch - begin end...
     */
    @Test
    public void test2() {
    
    
        //创建一个大小为5的线程池
        ExecutorService service = Executors.newFixedThreadPool(5);
        //创建倒计时锁
        CountDownLatch latch = new CountDownLatch(3);
        //任务1
        service.submit(() -> {
    
    
            log.debug("begin...");
            sleep(2);
            log.debug("begin end...");
            latch.countDown();
        });
        //任务2
        service.submit(() -> {
    
    
            log.debug("begin...");
            sleep(4);
            log.debug("begin end...");
            latch.countDown();
        });
        //任务3
        service.submit(() -> {
    
    
            log.debug("begin...");
            sleep(6);
            log.debug("begin end...");
            latch.countDown();
        });
        //任务4
        service.submit(() -> {
    
    
            try {
    
    
                latch.await();
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
            log.debug("begin...");
            sleep(1);
            log.debug("begin end...");
        });

        for (; ; ) ;
    }

}

2.CountDownLatch应用

1.CountDownLatch应用-等待多线程准备完毕

package com.concurrent.p10;

import lombok.extern.slf4j.Slf4j;
import org.junit.Test;

import java.util.Arrays;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * CountDownLatch应用-等待多线程准备完毕
 */
@Slf4j(topic = "c.Test_CountDownLatchApplication")
public class Test_CountDownLatchApplication {
    
    

    public void sleep(long mills) {
    
    
        try {
    
    
            Thread.sleep(mills);
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
    }

    /**
     * 所有线程都执行到100%时,主线程才能继续执行
     *
     * [100%, 100%, 100%, 100%, 100%, 100%, 100%, 100%, 100%, 100%]
     * 15:48:59.578 [main] DEBUG c.Test_CountDownLatchApplication - 加载完成,开始!
     */
    @Test
    public void test1() throws InterruptedException {
    
    
        //创建大小10的线程池
        ExecutorService service = Executors.newFixedThreadPool(10);
        //创建倒计时锁对象
        CountDownLatch latch = new CountDownLatch(10);
        //模拟随机运行时间
        Random random = new Random();
        //进度数组
        String all[] = new String[10];

        for (int j = 0; j < 10; j++) {
    
    
            int k = j;
            service.submit(() -> {
    
    
                for (int i = 0; i <= 100; i++) {
    
    
                    sleep(random.nextInt(100));
                    all[k] = i + "%";
                    System.out.print("\r" + Arrays.toString(all));
                }
                latch.countDown();
            });
        }

        latch.await();
        log.debug("加载完成,开始!");
        service.shutdown();
    }

}

应用-同步等待多个远程调用结束

//TODO

猜你喜欢

转载自blog.csdn.net/qq_36109528/article/details/120649588