Android中需要等待多个异步操作返回结果的情况很常见。解决这个问题的一种常用方法是使用CountDownLatch
和ExecutorService
。在本文中,我们将通过一个具体的问题来演示如何使用这两个类来解决多个异步操作的等待问题。
假设我们需要从服务器上获取用户的姓名、年龄和地址信息。这三个信息都需要通过异步操作从服务器获取,然后在界面上显示出来。为了简化示例,我们使用Runnable
来模拟异步操作,并假设这些异步操作都需要1秒钟才能返回结果。
首先,我们需要定义一个User
类来保存用户信息。代码如下所示:
public class User {
private String name;
private int age;
private String address;
// 省略构造方法和getter/setter方法
}
接下来,我们使用CountDownLatch
和ExecutorService
来实现等待多个异步操作返回结果的功能。代码如下所示:
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class MainActivity {
private CountDownLatch latch;
private User user;
public void fetchData() {
latch = new CountDownLatch(3);
ExecutorService executor = Executors.newFixedThreadPool(3);
executor.execute(new Runnable() {
@Override
public void run() {
// 模拟从服务器获取姓名信息
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
user.setName("John");
latch.countDown();
}
});
executor.execute(new Runnable() {
@Override
public void run() {
// 模拟从服务器获取年龄信息
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
user.setAge(25);
latch.countDown();
}
});
executor.execute(new Runnable() {
@Override
public void run() {
// 模拟从服务器获取地址信息
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
user.setAddress("123 Main St");
latch.countDown();
}
});
try {
latch.await(); // 等待所有异步操作完成
} catch (InterruptedException e) {
e.printStackTrace();
}
// 所有异步操作完成后,在界面上显示用户信息
showUserInfo(user);
}
private void showUserInfo(User user) {
// 在界面上显示用户信息
}
}
上述代码中,我们首先创建了一个CountDownLatch
对象,并将其初始化为3,表示需要等待3个异步操作完成。然后,我们使用ExecutorService
创建了一个线程池,并将三个异步操作提交给线程池执行。每个异步操作都会在获取到服务器返回结果后,通过countDown()
方法减少CountDownLatch
的计数。
在主线程中,我们通过调用await()
方法来等待所有异步操作完成。一旦所有异步操作都完成,我们就可以在界面上展示用户信息。
为了更好地理解这个过程,我们可以使用序列图来描述。序列图可以清晰地展示各个组件的交互关系。下面是使用Mermaid语法的序列图:
sequenceDiagram
participant MainThread
participant ExecutorThread1
participant ExecutorThread2
participant ExecutorThread3
MainThread->>ExecutorThread1: execute(fetchName)
MainThread->>ExecutorThread2: execute(fetchAge)
MainThread->>ExecutorThread3: execute(fetchAddress)
ExecutorThread1->>MainThread: setName("John")
ExecutorThread2->>MainThread: setAge(25)
ExecutorThread3->>MainThread: setAddress("123 Main St")
MainThread->>MainThread: showUserInfo(user)
在序列图中,MainThread(主线程)通过execute()方法分别将fetchName、fetchAge和fetchAddress提交给ExecutorThread1、ExecutorThread2和ExecutorThread3(线程池中的线程)。然后,每个ExecutorThread在获取到服务器返回结果后,通过回调方法将结果传递给MainThread,并最终调用showUserInfo()方法在界面上展示用户信息。
通过以上代码和序列图的示例,我们可以清楚地看到如何使用CountDownLatch和ExecutorService来等待多个异步操作返回结果,并在主线程中展示这些结果。这种方法可以很好地解决Android中等待