package com.dianping.pigeon.remoting.provider.process.threadpool;
import com.dianping.pigeon.log.Logger;
import com.dianping.pigeon.log.LoggerLoader;
import com.dianping.pigeon.remoting.provider.config.PoolConfig;
import com.dianping.pigeon.threadpool.DynamicThreadPool;
import com.google.common.collect.Interner;
import com.google.common.collect.Interners;
import com.google.common.collect.Maps;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeUnit;
/**
* Created by chenchongze on 16/11/23.
*/
public class DynamicThreadPoolFactory {
private static final Logger logger = LoggerLoader.getLogger(DynamicThreadPoolFactory.class);
private static final Interner<PoolConfig> interner = Interners.newWeakInterner();
// poolConfig --> threadPool
private static final ConcurrentMap<PoolConfig, DynamicThreadPool> dynamicThreadPools = Maps.newConcurrentMap();
// for lion poolConfig
public static DynamicThreadPool getThreadPool(PoolConfig poolConfig) {
DynamicThreadPool threadPool = dynamicThreadPools.get(poolConfig);
if (threadPool != null && threadPool.getExecutor().isShutdown()) {
return null;
}
return threadPool;
}
public static void refreshThreadPool(PoolConfig poolConfig) {
DynamicThreadPool threadPool = dynamicThreadPools.get(poolConfig);
if (threadPool == null) {
synchronized (interner.intern(poolConfig)) {
threadPool = dynamicThreadPools.get(poolConfig);
if (threadPool == null) {
try {
threadPool = new DynamicThreadPool("Pigeon-Server-Request-Processor-" + poolConfig.getPoolName(),
poolConfig.getCorePoolSize(), poolConfig.getMaxPoolSize(),
poolConfig.getWorkQueueSize());
dynamicThreadPools.put(poolConfig, threadPool);
} catch (Throwable t) {
logger.warn("Error while creating threadPool of " + poolConfig + ".", t);
}
}
}
} else {
if (poolConfigChanged(poolConfig, threadPool)) {
synchronized (interner.intern(poolConfig)) {
threadPool = dynamicThreadPools.get(poolConfig);
if (threadPool != null && poolConfigChanged(poolConfig, threadPool)) {
threadPool.setCorePoolSize(poolConfig.getCorePoolSize());
threadPool.setMaximumPoolSize(poolConfig.getMaxPoolSize());
threadPool.setWorkQueueCapacity(poolConfig.getWorkQueueSize());
}
}
}
}
}
public static void closeThreadPool(PoolConfig poolConfig) {
DynamicThreadPool threadPool = dynamicThreadPools.get(poolConfig);
if (threadPool != null) {
synchronized (interner.intern(poolConfig)) {
threadPool = dynamicThreadPools.get(poolConfig);
if (threadPool != null) {
try {
threadPool.getExecutor().shutdown();
//threadPool.getExecutor().awaitTermination(5, TimeUnit.SECONDS);
dynamicThreadPools.remove(poolConfig);
} catch (Throwable t) {
logger.warn("Error when shutting down old pool.", t);
}
}
}
}
}
private static boolean poolConfigChanged(PoolConfig poolConfig, DynamicThreadPool threadPool) {
return poolConfig.getCorePoolSize() != threadPool.getCorePoolSize()
|| poolConfig.getMaxPoolSize() != threadPool.getMaximumPoolSize()
|| poolConfig.getWorkQueueSize() != threadPool.getWorkQueueCapacity();
}
}