前面描述的线程池的创建方式大都是Executors类中创建出来,基于ThreadPoolExecutor去new出来实现的。
我们为什么要自定义线程池
- 在线程池ThreadPoolExecutor中提供了7个参数,都作为非常核心的属性,在线程池去执行任务的时候,每个参数都有决定性的作用。
- 采用JDK自定义的方式去创建线程池,核心参数只有两个(int,ThreadFactory),线程数量和线程延迟时间。对线程池的控制粒度不够细致,不一定能适配业务的需求。因此在阿里的代码规约之中推荐使用ThreadPoolExecutor去new并设置相关的核心属性。
ThreadPoolExecutor的核心参数展示
- int corePoolSize:核心的工作线程,当前任务执行结束之后不会被销毁。
- int maximumPoolSize:最大工作线程,代表当前线程池中一共可以有多少个工作线程。
- long keepAliveTime:非核心工作线程在阻塞队列中的等待时间,超过时间可以被干掉了。
- TimeUnit unit:非核心工作线程在阻塞队列中等待的时间单位。
- BlockingQueue workQueue:提交的任务在没有核心工作线程处理时,先将任务放到阻塞队列中。
- ThreadFactory threadFactory:构建线程(只是构建thread对象),可以设置thread的一些信息。
- RejectedExecutionHandler handler:当前线程无法处理投递过来的任务,执行当前的拒绝策略。
ThreadPoolExecutor的应用
介绍一下JDK提供的五种拒绝策略
四种写好的,一种自定义。
- AbortPolicy:该拒绝策略会在无法处理任务时候抛出异常。
- CallerRunsPolicy:当前拒绝策略会将自身无法处理的任务交给调用者处理。
- DiscardPolicy:当前拒绝策略会在线程池无法处理任务的时候将任务直接丢弃,在代码中什么都不做,要是想日志啥的可以没有可以使用这个拒绝策略,不然不要轻易使用。
- DiscardOldestPolicy:当前拒绝策略会在线程池无法处理任务的时候,将阻塞队列中最早的任务丢弃,将当前任务再次交给线程池处理。
- 自定义Policyl:根据自己的业务需求,自定义拒绝策略。可以将任务丢到数据库中,也可以做其他的操作。