先根据threadPoolKey尝试从threadPools这个ConcurrentHashMap<String, HystrixThreadPool>中获取,即从线程池缓存中获取,有就直接返回previouslyCached之前的缓存,如果没有,synchromized对HystrixThreadPool类上锁后,再次判断还是没有threadPoolKey的缓存,就 new HystrixThreadPoolDefault(threadPoolKey, propertiesBuilder)
//----------new HystrixThreadPoolDefault(threadPoolKey, propertiesBuilder) public HystrixThreadPoolDefault(HystrixThreadPoolKey threadPoolKey, HystrixThreadPoolProperties.Setter propertiesDefaults) { this.properties = HystrixPropertiesFactory.getThreadPoolProperties(threadPoolKey, propertiesDefaults); //threadPoolProperties HystrixConcurrencyStrategy concurrencyStrategy = HystrixPlugins.getInstance().getConcurrencyStrategy(); //并发策略 this.queueSize = properties.maxQueueSize().get(); //线程池队列大小 //创建HystrixThreadPoolMetrics,其中concurrencyStrategy.getThreadPool()会创建线程池 this.metrics = HystrixThreadPoolMetrics.getInstance(threadPoolKey, concurrencyStrategy.getThreadPool(threadPoolKey, properties), properties); this.threadPool = this.metrics.getThreadPool(); this.queue = this.threadPool.getQueue(); /* strategy: HystrixMetricsPublisherThreadPool */ HystrixMetricsPublisherFactory.createOrRetrievePublisherForThreadPool(threadPoolKey, this.metrics, this.properties); } //----------HystrixConcurrencyStrategy#getThreadPool(HystrixThreadPoolKey, HystrixThreadPoolProperties) // concurrencyStrategy.getThreadPool()时会创建ThreadPoolExecutor public ThreadPoolExecutor getThreadPool(final HystrixThreadPoolKey threadPoolKey, HystrixThreadPoolProperties threadPoolProperties) { final ThreadFactory threadFactory = getThreadFactory(threadPoolKey); final boolean allowMaximumSizeToDivergeFromCoreSize = threadPoolProperties.getAllowMaximumSizeToDivergeFromCoreSize().get(); //是否允许maximumSize生效 final int dynamicCoreSize = threadPoolProperties.coreSize().get(); //动态coreSize final int keepAliveTime = threadPoolProperties.keepAliveTimeMinutes().get(); //大于coreSize的线程,未使用的保活时间 final int maxQueueSize = threadPoolProperties.maxQueueSize().get(); //线程队列最大值 final BlockingQueue<Runnable> workQueue = getBlockingQueue(maxQueueSize); //允许使用maximumSize if (allowMaximumSizeToDivergeFromCoreSize) { final int dynamicMaximumSize = threadPoolProperties.maximumSize().get(); //dynamicCoreSize > dynamicMaximumSize,打印error if (dynamicCoreSize > dynamicMaximumSize) { logger.error("Hystrix ThreadPool configuration at startup for : " + threadPoolKey.name() + " is trying to set coreSize = " + dynamicCoreSize + " and maximumSize = " + dynamicMaximumSize + ". Maximum size will be set to " + dynamicCoreSize + ", the coreSize value, since it must be equal to or greater than the coreSize value"); return new ThreadPoolExecutor(dynamicCoreSize, dynamicCoreSize, keepAliveTime, TimeUnit.MINUTES, workQueue, threadFactory); } //dynamicCoreSize <= dynamicMaximumSize,正常 else { return new ThreadPoolExecutor(dynamicCoreSize, dynamicMaximumSize, keepAliveTime, TimeUnit.MINUTES, workQueue, threadFactory); } } else { //不允许使用maximumSize return new ThreadPoolExecutor(dynamicCoreSize, dynamicCoreSize, keepAliveTime, TimeUnit.MINUTES, workQueue, threadFactory); } }至此,线程池创建完毕
结论threadPoolKey的默认值是groupKey,而groupKey默认值是@HystrixCommand标注的方法所在类名
可以通过在类上加@DefaultProperties( threadPoolKey="xxx" )设置默认的threadPoolKey
可以通过@HystrixCommand( threadPoolKey="xxx" ) 指定当前HystrixCommand实例的threadPoolKey
threadPoolKey用于从线程池缓存中获取线程池 和 初始化创建线程池,由于默认以groupKey即类名为threadPoolKey,那么默认所有在一个类中的HystrixCommand共用一个线程池
动态配置线程池 -- 可以通过hystrix.command.HystrixCommandKey.threadPoolKeyOverride=线程池key动态设置threadPoolKey,对应的HystrixCommand所使用的线程池也会重新创建,还可以继续通过hystrix.threadpool.HystrixThreadPoolKey.coreSize=n和hystrix.threadpool.HystrixThreadPoolKey.maximumSize=n动态设置线程池大小
注意: 通过threadPoolKeyOverride动态修改threadPoolKey之后,hystrixCommand会使用新的threadPool,但是老的线程池还会一直存在,并没有触发shutdown的机制