本文共 6015 字,大约阅读时间需要 20 分钟。
随着现代应用程序对并发处理要求的不断提高,Java 的线程池机制成为开发者的利手工具。本文将介绍 Java 线程池的几种常见种类及其使用方法,帮助开发者更好地理解线程池的特性和适用场景。
线程池是一种资源管理的机制,它允许程序高效地配置和使用多个线程来执行任务。通过线程池,开发者无需手动管理线程的生命周期,而是通过任务提交的方式,线程池会根据需求自动创建、管理和终止线程。常见的线程池种类包括 固定大小、单个、定时 和 缓存。
使用 Executors.newFixedThreadPool(int nThreads) 创建固定大小的线程池。
ExecutorService executor = Executors.newFixedThreadPool(3);
corePoolSize)。当线程数量达到最大值后,新任务会被 enqueue至队列中,直到核心线程空闲。// 创建固定大小线程池ExecutorService executor = Executors.newFixedThreadPool(3);// 提交任务for (int i = 0; i < 6; i++) { executor.execute(new MyTask(i));}executor.shutdown(); 使用 Executors.newSingleThreadExecutor() 创建单线程池。
ExecutorService executor = Executors.newSingleThreadExecutor();
// 创建单线程定时池ExecutorService executor = Executors.newSingleThreadScheduledExecutor();// 定期执行任务executor.scheduleAtFixedDelay(new Runnable(), 0, 5, TimeUnit.SECONDS);
ScheduledThreadPoolExecutor。ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(3);
使用 ThreadPoolExecutor 的构造方法直接指定 corePoolSize 和 maxPoolSize。
new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS, new SynchronousQueue<>());
// 创建缓存线程池ExecutorService executor = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS, new SynchronousQueue<>());
固定大小线程池使用无界队列(LinkedBlockingQueue)作为工作队列,其核心特点包括:
示例代码:
class MyTask implements Runnable { private int taskNum; public MyTask(int num) { this.taskNum = num; } @Override public void run() { System.out.println("Thread " + Thread.currentThread().getName() + "正在执行任务 " + taskNum); try { Thread.sleep(1000); // 模拟耗时任务 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Thread " + Thread.currentThread().getName() + "完成执行任务 " + taskNum); }}public class Demo { public static void main(String[] args) { ExecutorService executor = Executors.newFixedThreadPool(3); // 创建3个核心线程 for (int i = 0; i < 6; i++) { executor.execute(new MyTask(i)); } executor.shutdown(); }} 单个线程池与固定大小线程池的区别主要在于:
示例代码:
class MyTask implements Runnable { private int taskNum; public MyTask(int num) { this.taskNum = num; } @Override public void run() { System.out.println("Thread " + Thread.currentThread().getName() + "正在执行任务 " + taskNum); try { Thread.sleep(1000); // 模拟耗时任务 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Thread " + Thread.currentThread().getName() + "完成执行任务 " + taskNum); }}public class Demo { public static void main(String[] args) { ExecutorService executor = Executors.newSingleThreadExecutor(); for (int i = 0; i < 6; i++) { executor.execute(new MyTask(i)); } executor.shutdown(); }} 定时线程池适合需要在特定时间间隔触发任务执行的情景。例如发送定时邮件、定期检查系统状态等。
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();executor.scheduleWithFixedDelay(new Runnable(), initialDelay, delay, TimeUnit.SECONDS);
其中 initialDelay 表示第一次执行的延迟,delay 表示后续任务的固定执行间隔。
import java.util.concurrent.ScheduledExecutorService;import java.util.concurrent.TimeUnit;class MyTask implements Runnable { private int taskNum; public MyTask(int num) { this.taskNum = num; } @Override public void run() { try { System.out.println("Thread " + Thread.currentThread().getName() + "正在执行任务 " + taskNum); Thread.sleep(1000); // 模拟耗时任务 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Thread " + Thread.currentThread().getName() + "完成执行任务 " + taskNum); }}public class Demo { public static void main(String[] args) { ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); executor.scheduleWithFixedDelay(new MyTask(), 0, 3, TimeUnit.SECONDS); // 每隔3秒执行一次 executor.shutdown(); }} 缓存线程池的核心特点是支持动态创建和回收线程,适合任务负载波动较大的场景。其最大池大小为 Integer.MAX_VALUE,超出核心线程数的空闲线程会在60秒内若无新任务提交则终止。
ThreadPoolExecutor executor = new ThreadPoolExecutor( 0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS, new SynchronousQueue<>());
import java.util.concurrent.ThreadPoolExecutor;import java.util.concurrent.TimeUnit;class MyTask implements Runnable { private int taskNum; public MyTask(int num) { this.taskNum = num; } @Override public void run() { System.out.println("Thread " + Thread.currentThread().getName() + "正在执行任务 " + taskNum); try { Thread.sleep(1000); // 模拟耗时任务 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Thread " + Thread.currentThread().getName() + "完成执行任务 " + taskNum); }}public class Demo { public static void main(String[] args) { ThreadPoolExecutor executor = new ThreadPoolExecutor( 0, // corePoolSize Integer.MAX_VALUE, // maximumPoolSize 60, // keepAliveTime TimeUnit.SECONDS, // time unit new SynchronousQueue<>() // work queue ); for (int i = 0; i < 10; i++) { executor.execute(new MyTask(i)); } executor.shutdown(); }} 线程池是Java中处理并发任务的重要工具,其中固定大小、单个、定时和缓存线程池各有特点。选择合适的线程池类型,能够有效地优化程序性能和资源利用率。在实际开发中,根据任务的特性和负载情况,合理使用线程池,使程序更加高效和健壮。
转载地址:http://futjz.baihongyu.com/