软件编程
位置:首页>> 软件编程>> java编程>> Java使用CountDownLatch实现网络同步请求的示例代码

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

作者:抓手  发布时间:2022-04-23 18:40:52 

标签:Java,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执行
两个子线程都执行完毕,继续执行主线程

来源:https://blog.csdn.net/Anenan/article/details/128547521

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com