1.ExecutorService创建线程池的5种方法
1.1 Executors.newCachedThreadPool()
1.2 Executors.newFixedThreadPool(10)
1.3 Executors.newSingleThreadExecutor()
1.4 Executors.newScheduledThreadPool(10)
1.5 Executors.newWorkStealingPool()
线程池的实际应用,一般不直接通过 ExecutorService executorService =Executors.newCachedThreadPool()等方法创建
表设计
初始化线程池,根据不同业务场景创建多个线程池,加载至内存
private void initThreadPool() {
threadPoolInfoList = threadPoolInfoService.getThreadPoolInfoList();
for (ThreadPoolInfo threadPoolInfo : threadPoolInfoList) {
BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(threadPoolInfo.getQueueSize());
ThreadPoolExecutor threadPool = new ThreadPoolExecutor(threadPoolInfo.getCoreSize(), threadPoolInfo.getMaxSize(),
threadPoolInfo.getThreadKeepAliveTime(), TimeUnit.SECONDS, workQueue,
new DefaultThreadFactory(threadPoolInfo.getName()), new ThreadPoolExecutor.CallerRunsPolicy());//拒绝策略-调用主线程执行
multiThreadPool.put(threadPoolInfo.getName(), threadPool);
logger.info("初始化线程池[{}]成功。", threadPoolInfo.getName());
}
}
线程池工厂,主要是起到记录线程号的作用
public class DefaultThreadFactory implements ThreadFactory {
private String namePrefix;
private AtomicInteger number = new AtomicInteger(1);
private ThreadGroup threadGroup;
public DefaultThreadFactory() {
}
public DefaultThreadFactory(String namePrefix) {
this.namePrefix = namePrefix;
ThreadGroup root = ThreadUtil.getRootThreadGroup();
threadGroup = new ThreadGroup(root, namePrefix + "-pool");
}
@Override
public Thread newThread(Runnable r) {
Thread thread = new Thread(threadGroup, r);
thread.setName(threadGroup.getName() + "-" + number.getAndIncrement());
if (thread.isDaemon()) {
thread.setDaemon(false);
}
if (Thread.NORM_PRIORITY != thread.getPriority()) {
thread.setPriority(Thread.NORM_PRIORITY);
}
return thread;
}
}
客户端调用
//threadPoolImpl 可以是基础jar包线程池接口,业务客户端调用时传入:客户端service对象、service中调用方法、参数, 线程池名称
ThreadPool pool = SpringContextHolder.getBean("threadPoolImpl");
pool.submit(new RunnableTask(target, methodName, args), poolName);
//根据target,methodName,args 创建线程,利用反射在线程池中调用
public class RunnableTask implements Runnable {
private Object target;
private String methodName;
private Object[] args;
private Map<String, String> contextVar = new HashMap<>();
public RunnableTask(Object target, String methodName) {
this.target = target;
this.methodName = methodName;
contextVar.putAll(ServiceContext.getContext().getContextVar());
logger.debug("异步请求任务,上下文{}", contextVar);
}
public RunnableTask(Object target, String methodName, Object... args) {
this.target = target;
this.methodName = methodName;
this.args = args;
contextVar.putAll(ServiceContext.getContext().getContextVar());
logger.debug("异步请求任务,上下文{}", contextVar);
}
@Override
public void run() {
try {
ServiceContext context = ServiceContext.getContext();
context.getContextVar().clear();
context.addContextVar(contextVar);
logger.debug("开始执行任务:[target:{},methodName:{},contextVar:{},args:{}]", this.target, this.methodName, this.contextVar, this.args);
ReflectionUtil.methodInvoker(this.target, this.methodName, this.args);
logger.debug("执行任务完成:{}", this);
} catch (Throwable throwable) {
logger.error("执行队列任务异常->{}", this, throwable);
}
}
public void setArgs(Object... args) {
this.args = args;
}
}