面试题答案
一键面试- 定义线程池并设置拒绝策略:
在创建
ThreadPoolExecutor
时,可以通过构造函数的参数设置拒绝策略。Java提供了几种内置的拒绝策略,如AbortPolicy
(默认,队列满且线程池饱和时抛出RejectedExecutionException
)、CallerRunsPolicy
(将任务回退到调用者线程执行)、DiscardPolicy
(直接丢弃任务)、DiscardOldestPolicy
(丢弃队列中最老的任务,然后尝试提交当前任务)。
以下是使用CallerRunsPolicy
拒绝策略的示例代码:
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class ThreadPoolWithRejectionPolicy {
public static void main(String[] args) {
// 定义线程池核心线程数
int corePoolSize = 5;
// 定义线程池最大线程数
int maximumPoolSize = 10;
// 线程存活时间
long keepAliveTime = 10;
// 存活时间单位
TimeUnit unit = TimeUnit.SECONDS;
// 使用LinkedBlockingQueue作为任务队列
BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>(5);
// 创建线程池并设置CallerRunsPolicy拒绝策略
ThreadPoolExecutor executor = new ThreadPoolExecutor(
corePoolSize,
maximumPoolSize,
keepAliveTime,
unit,
workQueue,
new ThreadPoolExecutor.CallerRunsPolicy());
// 模拟提交任务
for (int i = 0; i < 20; i++) {
int taskNumber = i;
executor.submit(() -> {
System.out.println("Task " + taskNumber + " is being processed by " + Thread.currentThread().getName());
try {
// 模拟任务执行时间
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
}
// 关闭线程池
executor.shutdown();
}
}
在上述代码中:
- 首先创建了一个
LinkedBlockingQueue
作为任务队列,容量为5。 - 然后通过
ThreadPoolExecutor
的构造函数创建线程池,核心线程数为5,最大线程数为10,线程存活时间为10秒。 - 最后设置拒绝策略为
CallerRunsPolicy
,当队列满且线程池饱和时,任务将由调用者线程执行。
如果想使用其他拒绝策略,例如DiscardPolicy
,只需将new ThreadPoolExecutor.CallerRunsPolicy()
替换为new ThreadPoolExecutor.DiscardPolicy()
即可。同样,AbortPolicy
和DiscardOldestPolicy
也可以类似替换。