java线程池:
Java通过Executors提供四种线程池,分别为:
newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
下面我们来分析newCachedThreadPool:
这种类型的线程池特点是:
工作线程的创建数量几乎没有限制(其实也有限制的,数目为Interger. MAX_VALUE), 这样可灵活的往线程池中添加线程。
如果长时间没有往线程池中提交任务,即如果工作线程空闲了指定的时间(默认为1分钟),则该工作线程将自动终止。终止后,如果你又提交了新的任务,则线程池重新创建一个工作线程。
在使用CachedThreadPool时,一定要注意控制任务的数量,否则,由于大量线程同时运行,很有会造成系统瘫痪。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
执行结果:
发现10个线程都是使用的线程1,线程池为无限大,当执行第二个任务时第一个任务已经完成,会复用执行第一个任务的线程,而不用每次新建线程。
ScheduledExecutorService:
private final static ScheduledExecutorService m_executorService;
private static ConcurrentHashMap<String, ABTest> abtestContext = new ConcurrentHashMap<String, ABTest>();
static {
m_executorService = Executors.newScheduledThreadPool(1,
ABTestThreadFactory.create("ABTestDataManager", true));
getAbtestRefresh();
schedulePeriodicRefresh();
}
public static ABTest getAbtestByName(String abtestName) {
if (abtestContext == null || abtestContext.isEmpty()) {
logger.warn("abtestName:{},Failed to obtain abtest configuration content, global abtestContext empty", abtestName);
return null;
}
return abtestContext.get(abtestName);
}
private static void schedulePeriodicRefresh() {
m_executorService.scheduleAtFixedRate(
new Runnable() {
@Override
public void run() {
logger.debug("refresh getAbtestRefresh {}");
getAbtestRefresh();
}
}, 0, 60, TimeUnit.SECONDS);
}
private static synchronized void getAbtestRefresh() {
if (AbtestProUtil.getURL() == null) {
return;
}
List<UnitOpenDTO> unitOpenDTOList = HttpClientUtill.httpGetList(AbtestProUtil.getURL(), UnitOpenDTO.class);
if (unitOpenDTOList == null) {
logger.warn("Request that the abtest openlist be empty,url:" + AbtestProUtil.getURL());
return;
}
//cookie里bucketId保证选择版本,关闭的ab,cookie里还有这里会继续执行,每次做删减
ConcurrentHashMap<String, ABTest> aBTestDTOMap = new ConcurrentHashMap<String, ABTest>();
if (CollectionUtils.isEmpty(unitOpenDTOList)) {
abtestContext = aBTestDTOMap;
return;
}
for (UnitOpenDTO unitOpenDTO : unitOpenDTOList) {
if (unitOpenDTO == null || CollectionUtils.isEmpty(unitOpenDTO.getItemOpenDTOList())) {
continue;
}
ABTest abTest = new ABTest(unitOpenDTO);
aBTestDTOMap.put(unitOpenDTO.getName(), abTest);
}
abtestContext = aBTestDTOMap;
}