Java线程池:主线程、线程等待、子线程结束

在Java编程中,我们经常遇到需要同时执行多个任务的情况。为了提高效率和资源利用率,我们可以使用线程池来管理和调度这些任务。线程池是一种线程管理的技术,它允许我们在应用程序中创建多个线程,并将它们分配给不同的任务。本文将介绍Java线程池的基本概念,并通过代码示例演示如何使用线程池来管理任务的执行。

什么是线程池?

线程池是一组预先创建的线程,这些线程可用于执行多个任务。它允许我们重复使用线程,避免了线程创建和销毁的开销,提高了应用程序的性能和响应速度。线程池可以根据需要动态调整线程的数量,并提供了任务队列来保存等待执行的任务。

线程池的基本用法

在Java中,我们可以使用ThreadPoolExecutor类来创建和管理线程池。以下是一个简单的示例:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ThreadPoolExample {
    public static void main(String[] args) {
        // 创建线程池,设置线程数量为2
        ExecutorService executor = Executors.newFixedThreadPool(2);

        // 提交任务给线程池
        executor.submit(() -> {
            // 子线程执行的任务
            System.out.println("Task 1 is running");
        });

        executor.submit(() -> {
            // 子线程执行的任务
            System.out.println("Task 2 is running");
        });

        // 关闭线程池
        executor.shutdown();
    }
}

在上面的示例中,我们首先使用Executors类的newFixedThreadPool方法创建一个固定大小为2的线程池。然后,我们通过executor.submit方法提交两个任务给线程池执行,这两个任务将会在两个子线程中并发执行。最后,我们调用executor.shutdown方法关闭线程池。

线程等待和子线程结束

在某些情况下,我们可能需要等待线程池中的所有任务执行完毕,然后再继续执行主线程的后续操作。为了实现这个功能,我们可以使用CountDownLatch类来实现线程等待的机制。

CountDownLatch是一种同步辅助类,它允许一个或多个线程等待其他线程完成操作后再继续执行。以下是一个使用CountDownLatch的示例:

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ThreadPoolExample {
    public static void main(String[] args) throws InterruptedException {
        // 创建线程池,设置线程数量为2
        ExecutorService executor = Executors.newFixedThreadPool(2);
        // 创建CountDownLatch,设置计数器为2
        CountDownLatch latch = new CountDownLatch(2);

        // 提交任务给线程池
        executor.submit(() -> {
            // 子线程执行的任务
            System.out.println("Task 1 is running");
            latch.countDown(); // 任务执行完毕,计数器减1
        });

        executor.submit(() -> {
            // 子线程执行的任务
            System.out.println("Task 2 is running");
            latch.countDown(); // 任务执行完毕,计数器减1
        });

        // 等待所有任务执行完毕
        latch.await();

        // 关闭线程池
        executor.shutdown();
        
        // 主线程执行的任务
        System.out.println("All tasks are completed");
    }
}

在上面的示例中,我们首先创建一个CountDownLatch对象,并将计数器设置为2。然后,我们使用latch.countDown()方法在每个子线程的任务执行完毕后将计数器减1。接着,我们调用latch.await()方法让主线程等待计数器变为0,即等待所有任务执行完毕。最后,我们输出一条消息表示所有任务都已完成。

状态图

下面是一个简单的状态图,表示线程池的状态变化:

stateDiagram
    [*] --> Running
    Running --> Shutdown