ThreadPoolExecutor在任务提交时可能会遇到线程池已经饱和的情况,即所有的核心线程和队列都已经被占用,而且线程池不能再创建新的线程来执行任务。在这种情况下,ThreadPoolExecutor 会采用预定义的拒绝策略来处理这些无法执行的任务。
AbortPolicy(默认策略):
- 这是默认的拒绝策略。当线程池饱和时,新任务的提交将会抛出
RejectedExecutionException
,通知调用者发生了拒绝。
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
public class AbortPolicyExample {
public static void main(String[] args) {
// 创建ThreadPoolExecutor并指定AbortPolicy拒绝策略
ThreadPoolExecutor executor = new ThreadPoolExecutor(
1, // corePoolSize
2, // maximumPoolSize
0, // keepAliveTime
java.util.concurrent.TimeUnit.SECONDS,
new java.util.concurrent.LinkedBlockingQueue<>(1), // workQueue
new ThreadPoolExecutor.AbortPolicy()); // 拒绝策略
// 提交任务
executor.submit(() -> System.out.println("Task 1"));
executor.submit(() -> System.out.println("Task 2"));
executor.submit(() -> System.out.println("Task 3")); // 该任务将会触发拒绝策略
// 关闭线程池
executor.shutdown();
}
}
CallerRunsPolicy:
- 当线程池饱和时,新任务会在调用者线程中直接执行。这种策略可能会导致调用者线程被阻塞,因为它本来可能想要提交新的任务。
import java.util.concurrent.ThreadPoolExecutor;
public class CallerRunsPolicyExample {
public static void main(String[] args) {
// 创建ThreadPoolExecutor并指定CallerRunsPolicy拒绝策略
ThreadPoolExecutor executor = new ThreadPoolExecutor(
1, // corePoolSize
2, // maximumPoolSize
0, // keepAliveTime
java.util.concurrent.TimeUnit.SECONDS,
new java.util.concurrent.LinkedBlockingQueue<>(1), // workQueue
new ThreadPoolExecutor.CallerRunsPolicy()); // 拒绝策略
// 提交任务
executor.submit(() -> System.out.println("Task 1"));
executor.submit(() -> System.out.println("Task 2"));
executor.submit(() -> System.out.println("Task 3")); // 该任务将在调用者线程中执行
// 关闭线程池
executor.shutdown();
}
}
DiscardPolicy:
- 当线程池饱和时,新任务将被丢弃,没有任何处理。这可能导致丢失任务,不推荐在需要完全处理所有任务的情况下使用。
import java.util.concurrent.ThreadPoolExecutor;
public class DiscardPolicyExample {
public static void main(String[] args) {
// 创建ThreadPoolExecutor并指定DiscardPolicy拒绝策略
ThreadPoolExecutor executor = new ThreadPoolExecutor(
1, // corePoolSize
2, // maximumPoolSize
0, // keepAliveTime
java.util.concurrent.TimeUnit.SECONDS,
new java.util.concurrent.LinkedBlockingQueue<>(1), // workQueue
new ThreadPoolExecutor.DiscardPolicy()); // 拒绝策略
// 提交任务
executor.submit(() -> System.out.println("Task 1"));
executor.submit(() -> System.out.println("Task 2"));
executor.submit(() -> System.out.println("Task 3")); // 该任务将被丢弃
// 关闭线程池
executor.shutdown();
}
}
DiscardOldestPolicy:
- 当线程池饱和时,尝试将最早加入队列的任务丢弃,以便为新任务腾出空间。
import java.util.concurrent.ThreadPoolExecutor;
public class DiscardOldestPolicyExample {
public static void main(String[] args) {
// 创建ThreadPoolExecutor并指定DiscardOldestPolicy拒绝策略
ThreadPoolExecutor executor = new ThreadPoolExecutor(
1, // corePoolSize
2, // maximumPoolSize
0, // keepAliveTime
java.util.concurrent.TimeUnit.SECONDS,
new java.util.concurrent.LinkedBlockingQueue<>(1), // workQueue
new ThreadPoolExecutor.DiscardOldestPolicy()); // 拒绝策略
// 提交任务
executor.submit(() -> System.out.println("Task 1"));
executor.submit(() -> System.out.println("Task 2"));
executor.submit(() -> System.out.println("Task 3"));
executor.submit(() -> System.out.println("Task 4")); // 该任务将会替换掉最早的任务
// 关闭线程池
executor.shutdown();
}
}