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