线程池是一种用于管理线程的强大工具,可提高性能并减少资源消耗。线程池主要通过Java自带的ThreadPoolExecutor类实现,使用线程池可以避免线程频繁创建和销毁的资源消耗,提高了线程的复用率,同时也可以控制线程的数量,防止线程数量过多导致系统负载过重。线程池的构建方法、线程池的类型以及线程池的拒绝策略在中有详细介绍。
线程池的拒绝策略是指当线程池中线程数量达到最大值,且队列已满无法继续添加任务时,如何处理这些被拒绝的任务。Java中提供了四种拒绝策略:AbortPolicy、CallerRunsPolicy、DiscardPolicy和DiscardOldestPolicy,分别对应抛出异常、在调用线程中运行、直接丢弃和丢弃队列最前面的任务。这些拒绝策略在中有详细介绍。
不同的拒绝策略适用于不同的场景。下面将分别介绍几种线程池拒绝策略的使用场景:
-
AbortPolicy:这是默认的拒绝策略,当线程池中的线程数达到最大值,且队列已满时,尝试添加任务会抛出RejectedExecutionException异常。这种策略适用于任务必须保证全部执行的场景,因为它能够明确地告诉调用者任务已经被拒绝,需要重新安排或者进行其它的处理。但是这种策略可能会导致调用者无法处理任务被拒绝的情况,因此需要在使用时慎重考虑。在中有详细介绍。
-
CallerRunsPolicy:当线程池中的线程数达到最大值,且队列已满时,新任务将在调用线程中运行。这种策略适用于任务量不大,但任务执行时间较长的场景,因为它能够避免线程池中的线程被长时间占用,从而防止线程饥饿。在中提到了一个实际场景,即一个http推送平台,当线程池被占满时,设置为CallerRunsPolicy策略,可以让DelayQueuePollingTask这个线程感知到这种情况,停止去数据库获取待推送任务,从而避免线程饥饿。
-
DiscardPolicy:当线程池中的线程数达到最大值,且队列已满时,新任务将被直接丢弃,不会给调用者任何反馈。这种策略适用于任务量较大,但是任务的重要性较低,因为它能够避免线程池被过多的低优先级任务占满。但是这种策略可能会导致一些任务被丢弃而无法执行,因此需要在使用时慎重考虑。在中有详细介绍。
-
DiscardOldestPolicy:当线程池中的线程数达到最大值,且队