Java 标准库中提供了哪些内置的线程池实现?请列举并说明其特点。

参考回答
Java 标准库中的 Executors 工具类提供了以下常用的内置线程池实现:

newFixedThreadPool(int nThreads):

创建一个固定大小的线程池。

线程池中的线程数始终保持为 nThreads。

适用于需要限制线程数量的场景。

newCachedThreadPool():

创建一个缓存线程池。

如果线程空闲且超过 60 秒未被使用,会被回收;如果有新任务,会复用已有线程或创建新线程。

适用于短时间内有大量任务的场景。

newSingleThreadExecutor():

创建一个单线程的线程池。

确保任务按提交顺序串行执行。

适用于需要顺序执行任务的场景。

newScheduledThreadPool(int corePoolSize):

创建一个支持定时任务和周期性任务的线程池。

可以延迟执行任务或按固定频率执行任务。

适用于需要定时调度的场景。

详细讲解与拓展
1. FixedThreadPool
特点:

线程池中的线程数是固定的。

如果任务数量超过线程数,超出的任务会进入等待队列。

示例代码:

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

public class FixedThreadPoolExample {
public static void main(String[] args) {
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);

for (int i = 1; i <= 5; i++) {
int taskId = i;
fixedThreadPool.execute(() -> {
System.out.println(“Task ” + taskId + ” executed by ” + Thread.currentThread().getName());
});
}

fixedThreadPool.shutdown();
}
}
输出:

Task 1 executed by pool-1-thread-1
Task 2 executed by pool-1-thread-2
Task 3 executed by pool-1-thread-3
Task 4 executed by pool-1-thread-1
Task 5 executed by pool-1-thread-2
适用场景:

适合处理恒定数量的任务,例如固定数量的 IO 操作。

  1. CachedThreadPool
    特点:

线程池大小不固定,空闲线程会被回收,新任务到来时可创建新线程。

在任务数量非常大的场景下容易占用大量资源,需要注意控制任务提交速率。

示例代码:

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

public class CachedThreadPoolExample {
public static void main(String[] args) {
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();

for (int i = 1; i <= 5; i++) {
int taskId = i;
cachedThreadPool.execute(() -> {
System.out.println(“Task ” + taskId + ” executed by ” + Thread.currentThread().getName());
});
}

cachedThreadPool.shutdown();
}
}
输出(线程可能动态创建):

Task 1 executed by pool-1-thread-1
Task 2 executed by pool-1-thread-2
Task 3 executed by pool-1-thread-3
Task 4 executed by pool-1-thread-4
Task 5 executed by pool-1-thread-5
适用场景:

适合执行大量短时间的小任务,例如请求处理。

  1. SingleThreadExecutor
    特点:

只有一个线程,所有任务按提交顺序依次执行。

线程异常终止时,会创建一个新线程继续执行任务。

示例代码:

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

public class SingleThreadExecutorExample {
public static void main(String[] args) {
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();

for (int i = 1; i <= 3; i++) {
int taskId = i;
singleThreadExecutor.execute(() -> {
System.out.println(“Task ” + taskId + ” executed by ” + Thread.currentThread().getName());
});
}

singleThreadExecutor.shutdown();
}
}
输出:

Task 1 executed by pool-1-thread-1
Task 2 executed by pool-1-thread-1
Task 3 executed by pool-1-thread-1
适用场景:

适合需要任务严格顺序执行的场景,例如日志写入。

  1. ScheduledThreadPool
    特点:

支持定时执行任务或周期性执行任务。

提供方法:

schedule(Runnable, delay, TimeUnit):延迟执行任务。

scheduleAtFixedRate(Runnable, initialDelay, period, TimeUnit):按固定速率周期执行任务。

scheduleWithFixedDelay(Runnable, initialDelay, delay, TimeUnit):按固定延迟周期执行任务。

示例代码:

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class ScheduledThreadPoolExample {
public static void main(String[] args) {
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(2);

    // 延迟 2 秒执行任务
    scheduledThreadPool.schedule(() -> {
        System.out.println("Task executed after delay");
    }, 2, TimeUnit.SECONDS);

    // 每 3 秒执行一次任务
    scheduledThreadPool.scheduleAtFixedRate(() -> {
        System.out.println("Periodic task executed");
    }, 1, 3, TimeUnit.SECONDS);

    // 关闭线程池,延时10秒
    scheduledThreadPool.schedule(() -> scheduledThreadPool.shutdown(), 10, TimeUnit.SECONDS);
}

}
输出示例:

Periodic task executed
Task executed after delay
Periodic task executed
Periodic task executed

适用场景:

定时任务,如定期清理缓存、监控系统状态等。

扩展:ThreadPoolExecutor
以上 Executors 创建的线程池实际上是 ThreadPoolExecutor 的封装,ThreadPoolExecutor 提供更灵活的配置:

核心线程数(corePoolSize):线程池中始终存活的线程数量。

最大线程数(maximumPoolSize):线程池中允许的最大线程数量。

任务队列:用于存储等待执行的任务。

拒绝策略:当线程池饱和时的任务处理策略(如抛异常、丢弃任务等)。

自定义线程池示例:

import java.util.concurrent.*;

public class CustomThreadPoolExample {
public static void main(String[] args) {
ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
2, // 核心线程数
5, // 最大线程数
60, // 空闲线程存活时间
TimeUnit.SECONDS,
new LinkedBlockingQueue<>(10) // 任务队列
);

for (int i = 1; i <= 15; i++) {
int taskId = i;
threadPool.execute(() -> {
System.out.println(“Task ” + taskId + ” executed by ” + Thread.currentThread().getName());
});
}

threadPool.shutdown();
}
}
总结
线程池类型 特点 适用场景
FixedThreadPool 固定线程数,任务超出线程数会进入队列 任务量稳定的场景,如处理固定数量的请求
CachedThreadPool 线程数不固定,空闲线程会被回收 大量短期任务的场景,如高并发请求处理
SingleThreadExecutor 单线程,任务按顺序执行 保证任务顺序执行的场景,如日志写入
ScheduledThreadPool 支持延迟和周期性任务 定时任务,如监控、缓存清理

发表评论

后才能评论