当前位置: 首页 > 图灵资讯 > 技术篇> Java 异步线程如何让主线程先跑完再走

Java 异步线程如何让主线程先跑完再走

来源:图灵教育
时间:2024-01-25 13:31:52

Java 异步线程如何让主线程先跑完再走?

引言

在开发过程中,我们经常遇到需要异步处理的情况,如发送网络请求、执行耗时操作等。但有时我们希望主线程能够等待异步线程执行,以确保数据的一致性和正确性。本文将通过使用介绍一个解决方案 Java 中的 CountDownLatch 实现等待异步线程执行主线程的效果。

问题分析

假设我们有一个场景,我们需要从多个接口获取数据,然后进行数据处理和显示。由于接口请求是平行的,我们需要等待所有接口请求完成后才能进行数据处理和显示。一种常见的实现方法是使用它 CountDownLatch。

CountDownLatch解决方案 简介

CountDownLatch 是 Java.util.concurrent 包中提供的同步工具类用于控制多个线程之间的执行顺序。主要有两种方法:

  • await():让调用该方法的线程等待,直到计数器的值为 0。
  • countDown():减少计数器的值 1。

CountDownLatch 创建指定初始值的工作原理是: CountDownLatch 对象,再调用多个线程 countDown() 减少计数器的方法 1 操作时,当计数器的值减少到 0 时,调用 await() 该方法的线程将被唤醒并继续执行。

示例场景

假设我们需要从三个不同的接口中获取数据,并在所有接口请求完成后处理和显示数据。首先,我们定义了一种获取接口数据的方法:

public class DataService {    public static String getDataFromApi(String apiUrl) {        // 模拟发送请求并返回数据        try {            Thread.sleep(1000); // 模拟耗时操作        } catch (InterruptedException e) {            e.printStackTrace();        }        return "Data from " + apiUrl;    }}

然后我们创建一个主线程和三个异步线程并使用它 CountDownLatch 控制主线程,等待异步线程完成。代码如下:

import java.util.concurrent.CountDownLatch;public class MainThreadExample {    public static void main(String[] args) {        final CountDownLatch latch = new CountDownLatch(3);        Thread thread1 = new Thread(() -> {            String data = DataService.getDataFromApi("api1");            System.out.println(data);            latch.countDown();        });        Thread thread2 = new Thread(() -> {            String data = DataService.getDataFromApi("api2");            System.out.println(data);            latch.countDown();        });        Thread thread3 = new Thread(() -> {            String data = DataService.getDataFromApi("api3");            System.out.println(data);            latch.countDown();        });        thread1.start();        thread2.start();        thread3.start();        try {            latch.await(); // 等待所有异步线程完成        } catch (InterruptedException e) {            e.printStackTrace();        }        System.out.println("All tasks completed. Start data processing and display.");        // 处理和显示数据    }}

在上述代码中,我们创建了初始值 3 的 CountDownLatch 对象 latch,然后创建了三个异步线程 thread1thread2thread3。我们通过调用每个异步线程 DataService.getDataFromApi() 该方法模拟发送请求并获取数据,并输出到控制台。同时,我们在每个异步线程的末尾调用它 latch.countDown() 方法是减少计数器的值 1。

在主线程中,我们首先启动了三个异步线程,然后调用它们 latch.await() 该方法等待所有异步线程的执行。当计数器的值减少到 0 主线程将继续执行并输出提示信息 "All tasks completed. Start data processing and display."。此时,我们可以在这个位置进行数据处理和显示。

流程图

下图显示了上述示例中主线程和异步线程的执行流程图:

flowchart TD    A[主线程] --> B[异步线程1]    A[主线程]