首页 > 图灵资讯 > 技术篇>正文
java线程池使用 spring boot线程池
2023-06-07 09:41:56
1.说明
*这是我认为的,可能不是所有正确的,如果有错误,也希望纠正1)线程池,线程池根据配置,允许最大n线同时执行2)序列,像列表,但它是一个Thread对象,线程池将从任务线程的序列,然后执行3)需求是现有订单,需要调用三方接口查询状态,所有一般思路都是:1).需要验证的定时任务2).在线程序列中加入3).如果需要在序列中执行,则应处理线程池
2.步骤(0).创建配置类
在以后使用时,需要从中取注springservice等。@Resource
import org.springframework.beans.BeansException;import org.springframework.context.ApplicationContext;import org.springframework.context.ApplicationContextAware;import org.springframework.stereotype.Component;@Componentpublic class BeanContext implements ApplicationContextAware { // Spring应用上下文环境 private static ApplicationContext applicationContext; /* * Applicationcontextaware实现 接口,这种方法必须实现; * 通过传输aplicationcontext参数初始成员变量aplicationtextion */ public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { BeanContext.applicationContext = applicationContext; } public static ApplicationContext getApplicationContext(){ return applicationContext; } @SuppressWarnings("unchecked") public static <T> T getBean(String name) throws BeansException { return (T)applicationContext.getBean(name); } public static <T> T getBean(Class<T> clz) throws BeansException { return (T)applicationContext.getBean(clz); }}
(1).创建线程池和序列
我创建了一个新的配置类别,你也可以在启动类别中创建序列,然后创建线程,将创建的序列引入到线程池中,看看创建线程池的几个关键参数
参数
解释
corePoolSize
我把核心线程池的大小理解为最大并行线程数
maximumPoolSize
最大线程池大小
keepAliveTime
线程的最大空闲时间
TimeUnit.SECONDS
我没有仔细检查时间(秒)的用途。
blockingQueue
对应序列
代码如下
import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import java.util.concurrent.ArrayBlockingQueue;import java.util.concurrent.ThreadPoolExecutor;import java.util.concurrent.TimeUnit;@Slf4j@Configurationpublic class ThreadPoolConfig { /** * 创建序列 * @return queue */ @Bean(name = "orderCheckQueue") public ArrayBlockingQueue<Runnable> orderCheckQueue(){ ArrayBlockingQueue<Runnable> objects = new ArrayBlockingQueue<>(5000); log.info(“订单验证序列初始化”); return objects; } /** * 创建线程池 * @param blockingQueue queue * @return pool */ @Bean(name = "orderCheckThreadPool") public ThreadPoolExecutor orderCheckThreadPool(@Qualifier(value = "orderCheckQueue") ArrayBlockingQueue<Runnable> blockingQueue){ int corePoolSize = 8; int maximumPoolSize = 32; long keepAliveTime = 60; ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit.SECONDS, blockingQueue); threadPoolExecutor.prestartAllCoreThreads(); log.info(“订单验证线程池初始化”); return threadPoolExecutor; } }
(2)创建线程执行对象
不能在线程执行对象中使用@Resource
@Autowired
,需要用结构方法注入,从springcontext中取service对象Xorderinfodao是maper,演示注入方法Xorderinfoentity是我的订单类,在这里传输,然后在这里传输run()
验证和验证订单在方法中的步骤
import lombok.extern.slf4j.Slf4j;@Slf4jpublic class OrderVerifyExecutors implements Runnable{ XOrderInfoEntity order; /*用结构方法注入service*/ private final XOrderInfoDao orderInfoDao; 操作service*/*构造方法 public OrderVerifyExecutors(XOrderInfoEntity order){ this.order = order; this.orderInfoDao = BeanContext.getApplicationContext().getBean(XOrderInfoDao.class); } @Override public void run() {xxx ////线程应执行的事项 }}
(3)其实这里就可以了。有了线程池、序列和线程执行方法,只要药物使用定时任务,就可以将XOrderinfoentity对象添加到序列中。这里使用定时任务,如下
import lombok.extern.slf4j.Slf4j;import org.springframework.context.annotation.Profile;import org.springframework.scheduling.annotation.Scheduled;import org.springframework.stereotype.Component;import javax.annotation.Resource;import java.util.List;import java.util.concurrent.ArrayBlockingQueue;@Slf4j@Component//@Profile("beta)//只在生产环境中启动publicc class DalOrderJob { //注入分析序列 @Resource(name = "orderCheckQueue") private ArrayBlockingQueue<Runnable> orderCheckQueue; @Resource private XOrderInfoDao orderInfoDao; @Scheduled(cron = "1 0/5 * * * ?") public void methodRun() { ///发现订单,循环创建OrderverifyExecutors执行对象,并添加到序列中 List<XOrderInfoEntity> all = orderInfoDao.findAll(); all.forEach(item -> { orderCheckQueue.add(new OrderVerifyExecutors(item)); }); }}
需要注意的是,如果序列满了,就不会添加,也不会报错。添加前需要判断是否满了。如果满了,sleep(),以后再添加。这里需要检查的订单量不多,先不加。