来源:blog.csdn.net/dabusiGin/article/details/105327873/Executor不推荐。Executors类为我们提供了各种类型的线程池。常用的工厂方法有:类ThreadDemo{publicstaticvoidmain(String[]args){ExecutorServicees=Executors.newSingleThreadExecutor();}}我们用阿里巴巴的P3C检查代码的时候就被教育了!!!!阿里爸爸不允许创建这样的线程池。上面的警告很明确:“线程池不允许使用Executors创建,而是通过ThreadPoolExecutor创建。这种处理方式让写作的同学更加清楚线程池的运行规则,避免资源耗尽的风险.》(PS:编译器很少看到中文提示,对于英文不好的同学简直就是福音,喜极而泣!!!)强制使用ThreadPoolExecutor我们使用ThreadPoolExecutor来创建线程池:公共类ThreadDemo{publicstaticvoidmain(String[]args){ExecutorServicees=newThreadPoolExecutor(1,1,0L,TimeUnit.MILLISECONDS,newLinkedBlockingQueue(10),Executors.defaultThreadFactory(),newThreadPoolExecutor.DiscardPolicy());}}至此用P3C检查代码,终于没有报错了,华丽丽的分隔符之后,我们还需要从JDK源码的层面去深挖其中的原理,首先是staticmethodnewSingleThreadExecutor(),newFixedThreadPool(intnThreads),newCachedThreadPool()我们来看看它的源码实现(基于JDK8)。publicstaticExecutorServicenewSingleThreadExecutor(){returnnewFinalizableDelegatedExecutorService(newThreadPoolExecutor(1,1,0L,TimeUnit.MILLISECONDS,newLinkedBlockingQueue()));}publicstaticExecutorServicenewFixed(PreadnThreadPool(intnThreads)nThreads,0L,TimeUnit.MILLISECONDS,newLinkedBlockingQueue());}publicstaticExecutorServicenewCachedThreadPool(){returnnewThreadPoolExecutor(0,Integer.MAX_VALUE,60L,TimeUnit.SECONDS,newSynchronousQueue());}通过查看源码我们知道,上面三个静态方法的内部实现都使用了ThreadPoolExecutor类。难怪阿里爸爸会建议通过ThreadPoolExecutor来实现。原来Executors类的静态方法也用到了,不过只是帮我们配置一些参数而已。第二个是ThreadPoolExecutor类的构造函数。既然要直接使用ThreadPoolExecutor类,就需要自己配置初始化参数,了解它的构造方法势在必行。ThreadPoolExecutor类一共有四种构造方法,我们只需要了解其中一种即可,因为其他三种构造方法只是帮助我们配置一些默认参数,最后调用它。publicThreadPoolExecutor(intcorePoolSize,intmaximumPoolSize,longkeepAliveTime,TimeUnitunit,BlockingQueueworkQueue,ThreadFactorythreadFactory,RejectedExecutionHandlerhandler)参数含义为:corePoolSize:线程池的线程数;maximumPoolSize:线程池中的最大线程数量;keepAliveTime:当线程池中的线程数超过corePoolSize时,多长时间内多余的空闲线程会被销毁;unit:keepAliveTime的时间单位;workQueue:任务队列,已经提交但还未执行??的任务;threadFactory:线程工厂,用于创建线程,一般使用默认的,即Executors类的静态方法defaultThreadFactory();处理程序:拒绝策略。当有太多任务需要处理时如何拒绝任务。对于这些参数,你需要了解以下内容:corePoolSize和maximumPoolSize的关系首先,corePoolSize必须<=maximumPoolSize。其他关系如下:如果当前线程池的线程数=corePoolSize,它会尝试将任务添加到任务队列中。如果添加成功,任务会等待空闲线程取出来执行;如果队列已满,且当前线程池中的线程数=maximumPoolSize,则使用Rejection策略(JDK提供了四种,下面会介绍)。注意:关系3是针对有界队列的,无界队列永远不会满,所以只有前两种关系。workQueue参数workQueue指的是提交但未执行的任务队列。如果当前线程池中的线程数>=corePoolSize,它会尝试将任务添加到任务队列中。主要有以下几种类型:SynchronousQueue:直接提交到队列。SynchronousQueue没有容量,所以实际提交的任务不会加入任务队列,新任务总是提交给线程执行,如果没有空闲线程,尝试创建新线程,如果线程数已经达到最大值值(maximumPoolSize),执行拒绝策略。LinkedBlockingQueue:无界任务队列。当有新的任务到来时,如果系统中的线程数小于corePoolSize,线程池就会创建一个新的线程来执行任务;当系统线程数等于corePoolSize时,由于是无界任务队列,任务总能成功添加到任务队列中,所以线程数不再增加。如果任务创建的速度远大于任务处理的速度,无界队列会快速增长,直到内存耗尽。handlerJDK内置了四种拒绝策略:DiscardOldestPolicy策略:丢弃任务队列中最早加入的任务,尝试提交当前任务;CallerRunsPolicy策略:调用主线程执行被拒绝的任务,提供了一种简单的反馈控制机制,会减慢新任务的提交速度。DiscardPolicy策略:静默丢弃无法处理的任务,不做任何处理。AbortPolicy策略:直接抛出异常,阻止系统正常工作。此时,我们直接新建ThreadPoolExecutor类就不用慌了!!!!近期热点文章推荐:1.1000+Java面试题及答案(2022最新版)2.厉害了!Java协程来了。..3.SpringBoot2.x教程,太全面了!4.不要用爆破爆满画面,试试装饰者模式,这才是优雅的方式!!5.《Java开发手册(嵩山版)》最新发布,赶快下载吧!感觉不错,别忘了点赞+转发!