1、拒绝策略
1.1、拒绝策略是什么?
用于等待的阻塞队列满了,当前运行的线程数又已经达到了maximumPoolSize
,无法为新的任务服务,这个时候使用拒绝策略做出反馈。
1.2、JDK内置的拒绝策略
1.2.1、AbortPolicy(默认)
直接抛出RejectedExecutionException异常阻止系统的正常运行
1.2.2、CallerRunsPolicy
“调用者运行”一种调节机制,该策略既不会抛弃任务,也不会抛出异常,而是将某些任务回退到调用者,从而降低新任务的流量。
1.2.3、DiscardOldestPolicy
丢弃队列中等待最久的任务
1.2.4、DiscardPolicy
直接丢弃任务,不予处理,也不抛出异常。如果允许任务丢失,这是最好的一种方案。
1.3、以上内置的拒绝策略均实现了RejectExecutionHandler
接口
2、工作中单一的、固定数的、可变的三种创建线程池的方法,用哪一个比较多?
哪一个都不要用
- 生产上只能使用自定义的。
- JDK中Executors已经给你提供了,为什么不用?
阿里巴巴开发手册:
一、编程规约(六)并发处理
3.【强制】线程资源必须通过线程池提供,不允许在应用中自行显式创建线程。
4.【强制】线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险
说明:Executors返回的线程池对象弊端如下:
1)FixedThreadPool和SingleThreadPool:
允许的请求队列长队为Integer.MAX_VALUE
,可能会堆积大量的请求,从而导致OOM。
2)CachedThreadPool和ScheduleThreadPool:
允许创建线程数量为Integer.MAX_VALUE
,可能会创建大量的线程,从而导致OOM.
3、你在工作中是如何使用线程池的,是否自定义过线程池使用
package com.company;
import java.util.concurrent.*;
//第四种Java使用多线程的方式:使用线程池
public class MyThreadPoolDemo {
public static void main(String[] args) {
ExecutorService threadPool = new ThreadPoolExecutor(
2,
5,
5,
TimeUnit.SECONDS,
new LinkedBlockingDeque<Runnable>(3),
Executors.defaultThreadFactory(),
//new ThreadPoolExecutor.AbortPolicy());
//new ThreadPoolExecutor.CallerRunsPolicy());
//new ThreadPoolExecutor.DiscardPolicy());
new ThreadPoolExecutor.DiscardOldestPolicy());
//模拟十个用户,每一个用户对应一个外部请求
try
{
for (int i = 1; i <= 10 ; i++) {
threadPool.execute(()->{
System.out.println(Thread.currentThread().getName()+"\t办理业务");
});
//try{TimeUnit.MILLISECONDS.sleep(5);}catch (InterruptedException e){e.printStackTrace();}
}
}catch(Exception e){
e.printStackTrace();
}finally{
threadPool.shutdown();
}
}
public static void threadPoolInit()
{
//一池5线程,一个银行有五个工作人员
ExecutorService threadPool = Executors.newFixedThreadPool(5);//一池5线程
ExecutorService threadPool1 = Executors.newSingleThreadExecutor();//一池1线程
ExecutorService threadPool2 = Executors.newCachedThreadPool();//一池N线程,自动适配线程个数
//模拟十个用户,每一个用户对应一个外部请求
try
{
for (int i = 1; i <= 10 ; i++) {
threadPool.execute(()->{
System.out.println(Thread.currentThread().getName()+"\t办理业务");
});
//try{TimeUnit.MILLISECONDS.sleep(5);}catch (InterruptedException e){e.printStackTrace();}
}
}catch(Exception e){
e.printStackTrace();
}finally{
threadPool.shutdown();
}
}
}