线程资源必须通过线程池的方式提供,显示的创建线程池会造成创建大量同类线程而导致过度消耗内存或者“过度切换”的问题。
所以需创建一个线程池来统一管理线程,减少在创建和销毁线程上所消耗的是时间以及系统资源的开销。
代码如下:
package com.alltuu.common.util;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
/**
* @author hahaha
*/
public class ThreadPoolUtil {
/**
* 获取处理器数量
*/
private static final int CPUNUM = Runtime.getRuntime().availableProcessors();
//private static final int MAXMUNPOOLSIZE = 10;
/**
* 线程池最大容纳线程数,通过处理器数量来确定最佳线程数量的大小
*/
private static final int MAXMUNPOOLSIZE = 2*CPUNUM+1;
//private static final int COREPOOLSIZE = 5;
/**
* 核心线程数量大小
*/
private static final int COREPOOLSIZE = 2*CPUNUM;
/**
* 线程空闲后的存活时长
*/
private static final int KEEPALIVETIME = 30;
private static ThreadPoolExecutor executor = null;
private static ThreadPoolExecutor getExecutor(){
if(executor == null){
synchronized (ThreadPoolExecutor.class){
if(executor == null){
executor = new ThreadPoolExecutor(
COREPOOLSIZE,
MAXMUNPOOLSIZE,
KEEPALIVETIME,
//KeepAliveTime的时间单位(秒)
TimeUnit.SECONDS,
//任务过多时存储任务的一个阻塞队列
//new LinkedBlockingDeque<Runnable>(Integer.MAX_VALUE),
new LinkedBlockingDeque<Runnable>(500),
new ThreadFactory() {
private final AtomicInteger atomicInteger = new AtomicInteger(1); //初始计数为0
@Override
public Thread newThread(Runnable runnable) {
// getAndIncrement以原子的操作递增当前值并返回旧值。相当于++i操作
return new Thread(runnable,"ThreadPoolUtil-" + atomicInteger.getAndIncrement());
}
}, //线程的创建工厂
//线程池任务满载后采取的任务拒绝策略
//new ThreadPoolExecutor.DiscardOldestPolicy()
//线程池满载后采取由提交任务者执行这个任务的策略
new ThreadPoolExecutor.CallerRunsPolicy()
);
//设置核心线程空闲时间超过keepAliveTime值时释放线程
executor.allowCoreThreadTimeOut(true);
}
}
}
return executor;
}
/**
* 无返回值直接执行
* @param runnable
*/
public static void executor(Runnable runnable){
getExecutor().execute(runnable);
}
/**
* 有返回值
* @param callable
* @param <T>
* @return
*/
public static <T> Future<T> submit(Callable<T> callable){
return getExecutor().submit(callable);
}
}
写了个测试,感觉用处不大:
@Test
public void ThreadPoolTest1(){
for (int i = 1; i <= 10; i++) {
ThreadPoolUtil.executor(new Runnable() {
@Override
public void run() {
try {
System.out.println("此时有线程:"+Thread.currentThread());
System.out.println("开始执行任务");
Thread.sleep(10000);
System.out.println(Thread.currentThread()+"任务结束");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
}
第一次写,基本是参考网上完成的,记录一下。
目前线程池工具类太过单一,无法满足业务需求,后续需要继续改进。