摘要:从线程池创建源码深入分析创建线程池有哪些方式。本文分享自华为云社区《【高并发】从源码角度分析创建线程池究竟有哪些方式》,作者:冰河。在Java的高并发领域,线程池一直是绕不开的话题。一直有童鞋在使用线程池,但是如何创建线程池只停留在使用Executors工具类的方式上,那么创建线程池的方式有哪些呢?下面我们从线程池创建的源码来深入分析一下如何创建线程池。使用Executors工具类创建线程池。初学者在创建线程池时用的最多的是Executors工具类。使用这个工具类创建线程池非常简单。你不需要过多关注线程池的细节。你只需要传入必要的参数即可。Executors工具类提供了几种创建线程池的方法,如下所示。?Executors.newCachedThreadPool:创建一个可缓存的线程池。如果线程池的大小超过需要,可以灵活回收空闲线程。如果没有可回收线程,则创建一个新线程。?Executors.newFixedThreadPool:创建一个定长线程池,可以控制最大并发线程数,超出的线程会在队列中等待?Executors.newScheduledThreadPool:创建一个支持定时和周期任务的定长线程池execution?Executors.newSingleThreadExecutor:创建单线程线程池,使用唯一的工作线程执行任务,保证所有任务按指定顺序执行(先进先出或优先级)?Executors.newSingleThreadScheduledExecutor:创建单线程支持定时和周期性任务执行的线程池?Executors。newWorkStealingPool:创建一个并行级别的工作窃取线程池。Executors.newWorkStealingPool方法是Java8中新增的创建线程池的方法,可以为线程池设置并行级别,并发度和性能更高。除了这个方法,其他创建线程池的方法本质上都是调用ThreadPoolExecutor类的构造函数。例如,我们可以使用下面的代码来创建一个线程池。Executors.newWorkStealingPool();Executors.newCachedThreadPool();Executors.newScheduledThreadPool(3);使用ThreadPoolExecutor类创建线程池从代码结构上看,ThreadPoolExecutor类继承自AbstractExecutorService,也就是说ThreadPoolExecutor类具有AbstractExecutorService类的所有功能。由于Executors工具类中的线程池创建方法大多调用ThreadPoolExecutor类的构造函数,所以我们也可以直接调用ThreadPoolExecutor类的构造函数来创建线程池,而不使用Executors工具类。接下来我们看一下ThreadPoolExecutor类的构造函数。ThreadPoolExecutor类中的所有构造函数如下。publicThreadPoolExecutor(intcorePoolSize,intmaximumPoolSize,longkeepAliveTime,TimeUnitunit,BlockingQueueworkQueue){这个(corePoolSize,maximumPoolSize,keepAliveTime,unit,workQueue,Executors.defaultThreadFactory(),defaultHandler);}publicThreadPoolExecutor(intcorePoolSize,intmaximumPoolSize,longkeepAliveTime,TimeUnitunit,BlockingQueueworkQueue,ThreadFactorythreadFactory){this(corePoolSize,maximumPoolSize,keepAliveTime,unit,workQueue,threadFactory,defaultHandler);}公共线程池执行器(intcorePoolSize,intmaximumPoolSize,longkeepAliveTime,TimeUnit单元,BlockingQueueworkQueue,RejectedExecutionHandler处理程序){this(corePoolSize,maximumPoolSize,keepAliveTime,unit,workQueue,Executors.defaultThreadFactory(),handler);}publicThreadPoolExecutor(intcorePoolSize,intmaximumPoolSize,longkeepAliveTime,TimeUnitunit,BlockingQueueworkQueue,ThreadFactorythreadFactory,RejectedExecutionHandler处理程序){if(corePoolSize<0||maximumPoolSize<=0||maximumPoolSizeworkQueue,ThreadFactorythreadFactory,RejectedExecutionHandlerhandler){if(corePoolSize<0||maximumPoolSize<=0||thrownewIllegalArgumentException();如果(workQueue==null||threadFactory==null||handler==null)thrownewNullPointerException();this.acc=System.getSecurityManager()==null?null:AccessController.getContext();this.corePoolSize=corePoolSize;这.maximumPoolSize=maximumPoolSize;this.workQueue=workQueue;this.keepAliveTime=unit.toNanos(keepAliveTime);this.threadFactory=threadFactory;参数的含义和作用可以去《高并发之——不得不说的线程池与ThreadPoolExecutor类浅析》参考。可以调用ThreadPoolExecutor类的构造函数自行创建线程池。例如,我们可以使用下面的形式来创建一个线程池。新的ThreadPoolExecutor(0,Integer.MAX_VALUE,60L,TimeUnit.SECONDS,newSynchronousQueue());使用ForkJoinPool类创建线程池在Java8的Executors工具类中,新增了以下创建线程池的方法。publicstaticExecutorServicenewWorkStealingPool(intparallelism){returnnewForkJoinPool(parallelism,ForkJoinPool.defaultForkJoinWorkerThreadFactory,null,true);}publicstaticExecutorServicenewWorkStealingPool(){返回新的ForkJoinPool(Runtime.getRuntime().availableProcessors(),ForkJoinPool.defaultForkJoinWorkerThreadFactnull,true);}从源码来看是可以的,本质上是调用了ForkJoinPool类的构造函数来创建线程池,而且从代码结构来看,ForkJoinPool类继承自AbstractExecutorService抽象类。接下来我们看一下ForkJoinPool类的构造函数。publicForkJoinPool(){this(Math.min(MAX_CAP,Runtime.getRuntime().availableProcessors()),defaultForkJoinWorkerThreadFactory,null,false);}publicForkJoinPool(intparallelism){this(parallelism,defaultForkJoinWorkerThreadFactory,null,false);}publicForkJoinPool(intparallelism,ForkJoinWorkerThreadFactoryfactory,UncaughtExceptionHandlerhandler,booleanasyncMode){this(checkParallelism(parallelism),checkFactory(factory),handler,asyncMode?FIFO_QUEUE:LIFO_QUEUE,"ForkJoinPool-"+nextPoolId()+"-worker-");checkPermission();}privateForkJoinPool(intparallelism,ForkJoinWorkerThreadFactoryfactory,UncaughtExceptionHandlerhandler,intmode,StringworkerNamePrefix){this.workerNamePrefix=workerNamePrefix;这个.工厂=工厂;this.ueh=处理程序;这个.config=(并行度&SMASK)|模式;longnp=(long)(-parallelism);//偏移ctl计数this.ctl=((np<