前言
springboot项目里面自定义线程池,自定义一个拒绝策略,把拒绝的任务task放入到redis缓存中,定义在一个定时任务,定时去处理里面的任务
使用步骤
1.自定义MyTask
代码如下:
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.util.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
@Slf4j
public class MyTask implements Runnable{
private String taskId;
private String taskName;
private Long orderId;
@Autowired
private RedisUtil redisUtil;
public MyTask(String taskId,String taskName,Long orderId){
this.taskId=taskId;
this.taskName=taskName;
this.orderId=orderId;
}
public String getTaskId() {
return taskId;
}
public void setTaskId(String taskId) {
this.taskId = taskId;
}
public String getTaskName() {
return taskName;
}
public void setTaskName(String taskName) {
this.taskName = taskName;
}
public Long getOrderId() {
return orderId;
}
public void setOrderId(Long orderId) {
this.orderId = orderId;
}
@Override
public void run() {
try{
System.out.println("run taskId = "+this.taskId + " taskName "+this.getTaskName() + " orderId "+this.getOrderId());
Thread.sleep(1000);
System.out.println("end taskId = "+this.taskId + " taskName "+this.getTaskName() + " orderId "+this.getOrderId());
}catch (Exception e){
e.printStackTrace();
}
}
}
2.线程池
代码如下:
@Configuration
public class ThreadPoolConfig {
@Autowired
private RedisUtil redisUtil;
@Bean
public ThreadPoolTaskExecutor getThreadPoolExcutor(){
ThreadPoolTaskExecutor executor=new ThreadPoolTaskExecutor();
executor.setCorePoolSize(4);
executor.setMaxPoolSize(10);
executor.setKeepAliveSeconds(60);
executor.setQueueCapacity(100);
executor.setThreadNamePrefix("ThreadExcutor");
executor.setWaitForTasksToCompleteOnShutdown(true);
executor.setRejectedExecutionHandler(new MyRejected(redisUtil));
executor.initialize();
return executor;
}
}
该处使用的url网络请求的数据。
3.拒绝策略MyRejected
代码如下
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.util.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import java.util.concurrent.RejectedExecutionHandler;
@Slf4j
public class MyRejected implements RejectedExecutionHandler {
@Autowired
private RedisUtil redisUtil;
@Autowired
private RedisTemplate<String, Object> redisTemplate;
public MyRejected(RedisUtil redisUtil){
this.redisUtil=redisUtil;
}
public MyRejected(){
}
@Override
public void rejectedExecution(Runnable r, java.util.concurrent.ThreadPoolExecutor executor) {
try{
MyTask task = (MyTask)r;
JSONObject jsonObject=new JSONObject();
jsonObject.put("orderId",task.getOrderId());
jsonObject.put("taskeName",task.getTaskName());
redisUtil.lSet("threadPoolTask",jsonObject.toJSONString());
log.info("当前被拒绝任务为:" + r.toString());
}catch (Exception e){
e.printStackTrace();
}
}
}
4.测试线程和定时任务
代码如下
/**
* 测试线程池
* @return
*/
@GetMapping("/dealThreadPoolTask")
public void getMessageMq() {
Long size=redisUtil.lGetListSize("threadPoolTask");
if(size==0){
redisUtil.lSet("threadPoolTask",0);
}
log.info("自定义线程池成功");
for(int i=0;i<1000;i++){
MyTask myTask=new MyTask(String.valueOf(i),"线程"+i,1L);
threadPoolConfig.getThreadPoolExcutor().execute(myTask);
}
}
/**
*定时任务处理在redis里面保存的任务
*/
@Scheduled(cron = "0/5 * * * * ?")
@XxlJob(value = "ExecuteTaskTestJob")
public void execute() throws InterruptedException {
log.info("执行定时任务:从redis获取task任务,放入到线程池中");
String task=(String)redisTemplate.opsForList().rightPop("threadPoolTask");
log.info(task);
JSONObject jsonObject=JSONObject.parseObject(task);
MyTask myTask=new MyTask("redis001",jsonObject.getString("taskeName"),jsonObject.getLong("orderId"));
threadPoolConfig.getThreadPoolExcutor().execute(myTask);
}
演示结果
输入localhost:7010/pdfWord/dealThreadPoolTask
redis保存的任务
定时任务获取的任务,交给线程池处理