jdk1.5以后新增了java.util.concurrent包下的api,简化了多线程代码的开发,底层的实现都是ThreadPoolExecutor,在ThreadPoolExecutor的源码中我们可以看到四种种实现策略:
- CallerRunsPolicy:只要线程池没有关闭,就在调用者的线程中执行任务。一般在不允许失败、对性能要求不高、并发小的场景使用。
public static class CallerRunsPolicy implements RejectedExecutionHandler { public CallerRunsPolicy() { } public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { if (!e.isShutdown()) { r.run(); } } }
- AbortPolicy:直接抛异常,默认是这种策略。需要处理好异常,因为他会打断当前的执行流程。
public static class AbortPolicy implements RejectedExecutionHandler { public AbortPolicy() { } public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { throw new RejectedExecutionException("Task " + r.toString() + " rejected from " + e.toString()); } }
- DiscardPolicy:什么也不做,直接丢弃。
public static class DiscardPolicy implements RejectedExecutionHandler { public DiscardPolicy() { } public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { } }
- DiscardOldestPolicy:丢弃最老的请求,重试执行。
public static class DiscardOldestPolicy implements RejectedExecutionHandler { public DiscardOldestPolicy() { } public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { if (!e.isShutdown()) { e.getQueue().poll(); e.execute(r); } } }
以上是jdk的内置策略,在实际开发中可以根据自己业务需求,实现RejectedExecutionHandler自定义自己需要的策略,有很多第三方的拒绝策略,比如dubbo、netty、activemq中的线程池拒绝策略都是不错的,感兴趣的同学可以看下源码。