引言
当使用线程池管理任务时,如果使用无界队列(LinkedBlockingQueue)的线程池(newFixedThreadPool和newSingleThreadExecutor默认使用一个无界队列),如果所有线程都在执行任务,那么任务将在队列中等待,如果任务到达的速度大于线程执行的速度,那么队列将无限期等待。
更稳妥的管理策略是使用有界队列,如:ArrayBlockingQueue,有界的LinkedBlockingQueue,PriorityBlockingQueue。有界队列避免了资源耗尽的情况,但出现一个问题,队列填满后,新的任务该如何处理?这时,就出现了包和策略。
1、AbortPolicy(抛异常)
AbortPolicy,默认饱和策略,该策略会抛出未检查异常RejectedExecutionException,调用者可以捕获这个异常,然后根据自己的需求编写代码。比如:捕获异常并重新提交任务,该策略还算友好,至少抛弃之前会通知任务提交者。
2、DiscardPolicy(静默丢弃)
exec.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());
收下任务,但是不做任何事情,也不抛异常,调用者啥也不知道,一脸蒙B;
3、CallerRunsPolicy(调用者执行)
exec.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
提供了一种调节机制,它不抛弃任务,也不抛出异常,而是将任务的请求返回到请求者那里,由提交任务的线程去执行自己提交的任务。
4、DiscardOldestPolicy(抛弃等待最久的任务)
exec.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardOldestPolicy());
抛弃掉等待队列中等待最久的任务,将其移除队列,然后执行当前任务,对等待就的任务不利。