ThreadPoolExecutor
提供了以下四种常见的拒绝策略:
-
AbortPolicy
(抛出异常):- 这是默认的拒绝策略。
- 当任务无法被接收处理时,直接抛出
RejectedExecutionException
异常。 - 示例:
ThreadPoolExecutor executor = new ThreadPoolExecutor( 2, 5, 1, TimeUnit.MINUTES, new ArrayBlockingQueue<>(3), new ThreadPoolExecutor.AbortPolicy());
当任务提交超过线程池处理能力时,会抛出异常。
-
CallerRunsPolicy
(调用者执行):- 当任务无法被接收处理时,由提交任务的线程自己来执行该任务。
- 示例:
ThreadPoolExecutor executor = new ThreadPoolExecutor( 2, 5, 1, TimeUnit.MINUTES, new ArrayBlockingQueue<>(3), new ThreadPoolExecutor.CallerRunsPolicy());
当任务过多时,提交任务的线程会执行被拒绝的任务。
-
DiscardOldestPolicy
(丢弃最旧任务):- 丢弃任务队列中最旧的未处理任务,然后将新任务加入队列。
- 示例:
ThreadPoolExecutor executor = new ThreadPoolExecutor( 2, 5, 1, TimeUnit.MINUTES, new ArrayBlockingQueue<>(3), new ThreadPoolExecutor.DiscardOldestPolicy());
当新任务无法加入队列时,会丢弃队列头部的任务。
-
DiscardPolicy
(直接丢弃):- 直接丢弃新提交的无法处理的任务,不做任何处理。
- 示例:
ThreadPoolExecutor executor = new ThreadPoolExecutor( 2, 5, 1, TimeUnit.MINUTES, new ArrayBlockingQueue<>(3), new ThreadPoolExecutor.DiscardPolicy());
当无法处理新任务时,直接忽略该任务。
在实际应用中,应根据具体的业务需求选择合适的拒绝策略。如果任务非常重要且不能丢失,可能需要选择 CallerRunsPolicy
;如果希望保证线程池的稳定性,避免异常抛出,可以考虑 DiscardOldestPolicy
或 DiscardPolicy
。
除了上述四种常见的拒绝策略外,还可以自定义拒绝策略来满足特定的需求。
以下是一个简单的自定义拒绝策略示例,假设我们希望在任务被拒绝时将其记录到日志中:
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
public class CustomRejectedExecutionHandler implements RejectedExecutionHandler {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
// 记录到日志
System.out.println("任务被拒绝:" + r.toString());
}
}
然后在创建 ThreadPoolExecutor
时使用自定义的拒绝策略:
ThreadPoolExecutor executor = new ThreadPoolExecutor(
2, 5, 1, TimeUnit.MINUTES,
new ArrayBlockingQueue<>(3),
new CustomRejectedExecutionHandler());
通过这种方式,可以根据具体的业务逻辑和场景需求来实现个性化的拒绝处理方式。