面试题答案
一键面试- AbortPolicy(默认拒绝策略):
- 策略描述:直接抛出
RejectedExecutionException
异常。 - 适用场景:适用于希望在任务被拒绝时立即知晓并处理异常情况的场景,比如关键业务流程,不允许任务丢失,一旦任务无法执行就需要马上处理。
- 策略描述:直接抛出
- CallerRunsPolicy:
- 策略描述:当任务被拒绝添加时,会在调用
execute
方法的线程中直接执行被拒绝的任务。 - 适用场景:适用于对性能要求不是特别高,但是希望能尽量处理提交任务的场景,它会降低新任务的提交速度,缓解线程池的压力。
- 策略描述:当任务被拒绝添加时,会在调用
- DiscardPolicy:
- 策略描述:直接丢弃被拒绝的任务,不做任何处理。
- 适用场景:适用于那些对任务执行结果不关心,允许任务丢失的场景,比如一些日志记录任务,丢失几条记录对整体业务影响不大。
- DiscardOldestPolicy:
- 策略描述:丢弃队列中等待时间最长的任务,然后尝试将新任务添加到队列中。
- 适用场景:适用于处理优先级较高的任务场景,优先保证新提交的高优先级任务能被处理,而将等待时间过长的低优先级任务丢弃。
自定义拒绝策略
- 实现
RejectedExecutionHandler
接口,重写rejectedExecution
方法。示例代码如下:
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("Task " + r.toString() + " rejected from " + executor.toString());
}
}
- 在创建
ThreadPoolExecutor
时,将自定义的拒绝策略实例作为参数传入。示例代码如下:
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class CustomRejectionPolicyExample {
public static void main(String[] args) {
ThreadPoolExecutor executor = new ThreadPoolExecutor(
2,
4,
10,
TimeUnit.SECONDS,
new LinkedBlockingQueue<>(2),
new CustomRejectedExecutionHandler());
for (int i = 0; i < 10; i++) {
executor.execute(new Task("Task-" + i));
}
executor.shutdown();
}
}
class Task implements Runnable {
private String name;
public Task(String name) {
this.name = name;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " is processing " + name);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
上述代码展示了如何自定义拒绝策略并在 ThreadPoolExecutor
中使用。在 CustomRejectedExecutionHandler
类中实现了自定义的拒绝处理逻辑,在 CustomRejectionPolicyExample
类中创建了 ThreadPoolExecutor
并使用自定义拒绝策略。