Java等待子线程结束

在Java中,线程是一种轻量级的执行单元,可以同时运行多个线程来实现并发编程。在多线程编程中,有时候我们需要等待一个或多个子线程执行完毕后再进行后续的操作。

本文将介绍在Java中等待子线程结束的常用方法,并提供代码示例来说明如何实现。

为什么要等待子线程结束?

在并发编程中,我们通常会创建一个或多个子线程来执行一些耗时的操作,而主线程则负责管理和控制子线程。有时候,我们需要等待子线程执行完毕后再进行后续的操作,以确保数据的一致性或避免并发冲突。

例如,假设我们需要从多个网站上下载图片并保存到本地文件。我们可以使用多个子线程同时下载不同的图片,而主线程负责等待所有子线程下载完成后再进行文件保存操作。这样可以提高下载效率,并且保证所有图片都被下载完整。

等待子线程结束的方法

1. 使用join()方法

在Java中,每个线程对象都有一个join()方法,可以用来等待该线程执行完毕。调用join()方法会阻塞当前线程,直到目标线程执行完毕。

下面是一个使用join()方法等待子线程结束的示例代码:

public class MainThread {
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(new MyRunnable());
        thread.start();

        System.out.println("主线程开始等待子线程执行完毕...");

        // 等待子线程执行完毕
        thread.join();

        System.out.println("子线程执行完毕,继续执行主线程...");
    }
}

public class MyRunnable implements Runnable {
    @Override
    public void run() {
        System.out.println("子线程开始执行...");
        // 模拟耗时操作
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("子线程执行完毕...");
    }
}

在上面的代码中,创建了一个子线程thread,并调用start()方法启动线程。主线程调用join()方法等待子线程执行完毕。当子线程执行完毕后,主线程才会继续执行。

输出结果如下:

主线程开始等待子线程执行完毕...
子线程开始执行...
子线程执行完毕,继续执行主线程...

2. 使用CountDownLatch

CountDownLatch是Java中的一个同步辅助类,可以用来等待一个或多个线程执行完毕。它通过一个计数器来实现,计数器的初始值为线程的数量,每个线程执行完毕后,计数器减一,当计数器的值为0时,表示所有线程都执行完毕。

下面是一个使用CountDownLatch等待子线程结束的示例代码:

import java.util.concurrent.CountDownLatch;

public class MainThread {
    public static void main(String[] args) throws InterruptedException {
        CountDownLatch latch = new CountDownLatch(1);
        Thread thread = new Thread(new MyRunnable(latch));
        thread.start();

        System.out.println("主线程开始等待子线程执行完毕...");

        // 等待子线程执行完毕
        latch.await();

        System.out.println("子线程执行完毕,继续执行主线程...");
    }
}

public class MyRunnable implements Runnable {
    private CountDownLatch latch;

    public MyRunnable(CountDownLatch latch) {
        this.latch = latch;
    }

    @Override
    public void run() {
        System.out.println("子线程开始执行...");
        // 模拟耗时操作
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("子线程执行完毕...");

        // 执行完毕后将计数器减一
        latch.countDown();
    }
}

在上面的代码中,创建了一个CountDownLatch对象,并将初始值设置为1。子线程在执行完毕后调用countDown()方法将计数器减一