首页的数据报表,通过for循环查询redis中的数据,200条数据需要9秒左右,需要优化查询时间,用多线程查询。
1、利用 callable线程方法返回线程查询的数据
package com.demo.thread;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.demo.model.User;
import com.demo.service.UserService;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
/**
* @author:Tseng
* @description TODO
* @since: JDK1.8
* @version: 1.0
* @date: 2021/8/5 16:56
* 最后更新日期:
* 修改人:
* 复审人:
* @Copyright © 2021
*/
public class CallableThread implements Callable<List<User>> {
/** 数据集合 */
private List<User> list;
/** 每个线程处理的起始数据 */
private CountDownLatch begin;
/** 每个线程处理的结束数据 */
private CountDownLatch end;
private UserService userService = BeanContext.getBean(UserService.class);;
public CallableThread() {
}
public CallableThread(List<User> list, CountDownLatch begin, CountDownLatch end) {
this.list = list;
this.begin = begin;
this.end = end;
}
@Override
public List<User> call() {
List<User> retList = new ArrayList<>();
try {
if(ObjectUtils.isNotNull(list)){
for(User user: list){
User users = userService.getUser(carInfo.getName());
if(ObjectUtils.isNotNull(users)){
retList.add(users);
}
}
}
// 执行完让线程直接进入等待
begin.await();
System.out.println(Thread.currentThread().getName() + "===任务" + "执行完成===");
} catch (Exception e) {
e.printStackTrace();
} finally {
// 当一个线程执行完了计数要减一不然这个线程会被一直挂起
end.countDown();
}
return retList;
}
}
2、执行多线程的方法
package com.demo.thread;
import com.demo.model.User;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.*;
/**
* @author:Tseng
* @description TODO
* @since: JDK1.8
* @version: 1.0
* @date: 2021/8/5 17:00
* 最后更新日期:
* 修改人:
* 复审人:
* @Copyright © 2021
*/
public class DemoThread {
// 一个线程处理几条数据
public static int count = 15;
public static List<User> batchInsertByThread(List<User> list){
if (list == null || list.isEmpty()) {
return null;
}
// 数据集合大小
int listSize = list.size();
// 开启的线程数
int runSize = (listSize / count) + 1;
// 存放每个线程的执行数据
List<CarInfo> newList = null;
// 创建一个线程池,数量和开启线程的数量一样
ExecutorService executor = Executors.newFixedThreadPool(runSize);
// 创建两个个计数器
CountDownLatch begin = new CountDownLatch(1);
CountDownLatch end = new CountDownLatch(runSize);
List<Future<List<User>>> futures = new ArrayList<>();
// 创建一个存储所有返回值的list
List<User> listAll = Collections.synchronizedList(new ArrayList<>());
for (int i = 0; i < runSize; i++) {
/* 计算每个线程执行的数据 */
if ((i + 1) == runSize) {
int startIdx = (i * count);
int endIdx = list.size();
newList = list.subList(startIdx, endIdx);
} else {
int startIdx = (i * count);
int endIdx = (i + 1) * count;
newList = list.subList(startIdx, endIdx);
}
CallableThread PersionThread = new CallableThread(newList, begin, end);
futures.add(executor.submit(PersionThread));
}
begin.countDown();
try {
for(Future< List<User>> future : futures){
//合并操作
List<User> futureList= null;
try {
futureList= future.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
listAll.addAll(futureList);
}
end.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
executor.shutdown();
return listAll;
}
}
3、在线程内部使用手动获取service对象
package com.demo.thread;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
/**
* @author:Tseng
* @description TODO
* @since: JDK1.8
* @version: 1.0
* @date: 2021/8/6 11:54
* 最后更新日期:
* 修改人:
* 复审人:
* @Copyright © 2021
*/
@Component
public class BeanContext implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
BeanContext.applicationContext = applicationContext;
}
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
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);
}
}
4、调用多线程
DemoThread.batchInsertByThread(userList);