返回

任务执行被拒绝,线程池拒绝策略是什么?

后端

线程池拒绝策略

线程池拒绝策略是在线程池无法处理更多任务时所采取的措施。有四种标准的拒绝策略:

  • AbortPolicy :这种策略会抛出RejectedExecutionException异常,表示任务被拒绝,并且不会尝试在以后重新提交它。这是最简单、最直接的拒绝策略。但是,它也有一个缺点,就是会导致任务丢失。
  • CallerRunsPolicy :这种策略会在线程池无法处理更多任务时,由调用线程自己来执行任务。这种策略可以避免任务丢失,但可能会导致调用线程变慢或死锁。
  • DiscardOldestPolicy :这种策略会丢弃线程池中最旧的任务,以腾出空间来处理新任务。这种策略可以防止任务丢失,但可能会导致较旧的任务被丢弃,而较新的任务被处理。
  • DiscardPolicy :这种策略会简单地丢弃新任务,而不会尝试在以后重新提交它。这种策略与AbortPolicy非常相似,但它不会抛出RejectedExecutionException异常。

如何选择合适的拒绝策略

在选择拒绝策略时,需要考虑以下几个因素:

  • 任务的重要性 :如果任务非常重要,那么就应该选择一种不会导致任务丢失的拒绝策略,例如CallerRunsPolicy或DiscardOldestPolicy。
  • 线程池的利用率 :如果线程池的利用率很低,那么就可以选择一种更激进的拒绝策略,例如AbortPolicy或DiscardPolicy。
  • 系统资源 :如果系统资源紧张,那么就应该选择一种不会导致系统崩溃的拒绝策略,例如AbortPolicy或CallerRunsPolicy。

示例

以下是一个示例,演示了如何使用线程池和拒绝策略:

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

public class ThreadPoolDemo {

    public static void main(String[] args) {
        // 创建一个线程池,最大线程数为5
        ExecutorService executorService = Executors.newFixedThreadPool(5);

        // 提交10个任务到线程池
        for (int i = 0; i < 10; i++) {
            try {
                executorService.submit(() -> {
                    // 模拟任务执行
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("任务" + Thread.currentThread().getName() + "执行完成");
                });
            } catch (RejectedExecutionException e) {
                // 任务被拒绝,执行拒绝策略
                System.out.println("任务" + i + "被拒绝");
            }
        }

        // 关闭线程池
        executorService.shutdown();
    }
}

在上面的示例中,我们创建了一个线程池,最大线程数为5。然后,我们提交了10个任务到线程池。由于线程池的线程数已经满了,因此第6个任务和之后的任务都被拒绝了。此时,我们会执行拒绝策略,即打印出"任务6被拒绝"等信息。