Java使用CountDownLatch实现网络同步请求的示例代码

 更新时间:2023年01月04日 15:07:36   作者:抓手  
CountDownLatch 是一个同步工具类,用来协调多个线程之间的同步,它能够使一个线程在等待另外一些线程完成各自工作之后,再继续执行。被将利用CountDownLatch实现网络同步请求,异步同时获取商品信息组装,感兴趣的可以了解一下

CountDownLatch 是一个同步工具类,用来协调多个线程之间的同步,它能够使一个线程在等待另外一些线程完成各自工作之后,再继续执行。

这里是使用CountDownLatch和多线程完成商品信息异步组装:

import java.time.LocalDateTime;
import java.util.StringJoiner;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
 
/**
 * @author 向振华
 * @date 2023/01/04 14:01
 */
public class Test {
 
    public static void main(String[] args) {
 
        // 创建线程池
        ExecutorService executorService = Executors.newFixedThreadPool(10);
 
        CountDownLatch countDownLatch = new CountDownLatch(3);
 
        System.out.println("开始 " + LocalDateTime.now());
 
        StringJoiner sj = new StringJoiner("、");
 
        // 线程1
        executorService.execute(() -> {
            try {
                String do1 = do1();
                sj.add(do1);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                countDownLatch.countDown();
            }
        });
 
        // 线程2
        executorService.execute(() -> {
            try {
                String do2 = do2();
                sj.add(do2);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                countDownLatch.countDown();
            }
        });
 
        // 线程3
        executorService.execute(() -> {
            try {
                String do3 = do3();
                sj.add(do3);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                countDownLatch.countDown();
            }
        });
 
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
 
        System.out.println(sj.toString());
        System.out.println("完成 " + LocalDateTime.now());
    }
 
    private static String do1() {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("1查询商品规格信息");
        return "商品规格";
    }
 
    private static String do2() {
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("2查询商品价格信息");
        return "商品价格";
    }
 
    private static String do3() {
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("3查询商品图片信息");
        return "商品图片";
    }
}

输出结果:

开始 2023-01-04T14:16:40.441
1查询商品规格信息
3查询商品图片信息
2查询商品价格信息
商品规格、商品图片、商品价格
完成 2023-01-04T14:16:45.468

知识补充

1.背景

  • countDownLatch是在java1.5被引入,跟它一起被引入的工具类还有CyclicBarrier、Semaphore、concurrentHashMap和BlockingQueue。
  • 存在于java.util.cucurrent包下

2.概念

countDownLatch这个类使一个线程等待其他线程各自执行完毕后再执行。

是通过一个计数器来实现的,计数器的初始值是线程的数量。每当一个线程执行完毕后,计数器的值就-1,当计数器的值为0时,表示所有线程都执行完毕,然后在闭锁上等待的线程就可以恢复工作了。

3.源码

countDownLatch类中只提供了一个构造器:

//参数count为计数值
public CountDownLatch(int count) {  };  

类中有三个方法是最重要的:

//调用await()方法的线程会被挂起,它会等待直到count值为0才继续执行
public void await() throws InterruptedException { };   
//和await()类似,只不过等待一定的时间后count值还没变为0的话就会继续执行
public boolean await(long timeout, TimeUnit unit) throws InterruptedException { };  
//将count值减1
public void countDown() { };  

4.示例

普通示例

public class CountDownLatchTest {

    public static void main(String[] args) {
        final CountDownLatch latch = new CountDownLatch(2);
        System.out.println("主线程开始执行…… ……");
        //第一个子线程执行
        ExecutorService es1 = Executors.newSingleThreadExecutor();
        es1.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(3000);
                    System.out.println("子线程:"+Thread.currentThread().getName()+"执行");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                latch.countDown();
            }
        });
        es1.shutdown();

        //第二个子线程执行
        ExecutorService es2 = Executors.newSingleThreadExecutor();
        es2.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("子线程:"+Thread.currentThread().getName()+"执行");
                latch.countDown();
            }
        });
        es2.shutdown();
        System.out.println("等待两个线程执行完毕…… ……");
        try {
            latch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("两个子线程都执行完毕,继续执行主线程");
    }
}

结果集:

主线程开始执行…… ……
等待两个线程执行完毕…… ……
子线程:pool-1-thread-1执行
子线程:pool-2-thread-1执行
两个子线程都执行完毕,继续执行主线程

到此这篇关于Java使用CountDownLatch实现网络同步请求的示例代码的文章就介绍到这了,更多相关Java CountDownLatch网络同步请求内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 关于@Autowierd && @Resource 你真的了解吗

    关于@Autowierd && @Resource 你真的了解吗

    这篇文章主要介绍了关于@Autowierd && @Resource的具体使用,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-08-08
  • spring boot系列之集成测试(推荐)

    spring boot系列之集成测试(推荐)

    这篇文章主要介绍了spring boot系列集成测试,需要的朋友可以参考下
    2018-03-03
  • java socket大数据传输丢失问题及解决

    java socket大数据传输丢失问题及解决

    这篇文章主要介绍了java socket大数据传输丢失问题及解决,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-08-08
  • spring Bean的初始化过程解析

    spring Bean的初始化过程解析

    这篇文章主要介绍了spring Bean的初始化过程,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-03-03
  • 浅析Jmeter多用户token使用问题

    浅析Jmeter多用户token使用问题

    这篇文章主要介绍了Jmeter多用户token使用问题,通过具体的例子给大家介绍了Jmeter多用户token使用场景接口分析,需要的朋友可以参考下
    2021-10-10
  • Mybatis的介绍、基本使用、高级使用

    Mybatis的介绍、基本使用、高级使用

    这篇文章主要介绍了Mybatis的介绍、基本使用、高级使用,Mybatis是一款半自动的ORM持久层框架,具有较高的SQL灵活性,如何使用看这篇就够了,需要的朋友可以参考下
    2023-03-03
  • Mybatis中通过generator生成mapper、Dao、mapper.xml的方法

    Mybatis中通过generator生成mapper、Dao、mapper.xml的方法

    这篇文章主要介绍了Mybatis中通过generator生成mapper、Dao、mapper.xml的方法,需要的朋友可以参考下
    2017-01-01
  • java如何把逗号分隔的String字符串转int集合

    java如何把逗号分隔的String字符串转int集合

    这篇文章主要介绍了java实现把逗号分隔的String字符串转int集合,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-06-06
  • mybatis trim标签的使用详解

    mybatis trim标签的使用详解

    这篇文章主要介绍了mybatis trim标签的使用详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-06-06
  • Spring中的@PropertySource注解源码详细解析

    Spring中的@PropertySource注解源码详细解析

    这篇文章主要介绍了Spring中的@PropertySource注解源码详细解析,@PropertySource注解,标注在配置类@Configuration上面,下面主要分析一下@PropertySource注解的处理过程,也就是怎么把配置信息从.properies文件放到environment中的,需要的朋友可以参考下
    2024-01-01

最新评论