一个简单的多线程实现
1、配置扫描的类,线程使用的ApplicationContextUtils需要被扫描到
<context:component-scan base-package="com.glanway.zpparts.controller,com.glanway.zpparts.test"/>
2、编写一个ApplicationContextUtils对象的类,与上面设置的路径对应
package com.glanway.zpparts.test;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class ApplicationContextUtils implements ApplicationContextAware {
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringUtils.setApplicationContext(applicationContext);
}
}
3、编写一个获取Sservice的SpringUtils工具类,路径与上面配置的对应
package com.glanway.zpparts.test;
import org.springframework.context.ApplicationContext;
/**
* 注入获取service对象
* @author zp_ww
* @date 2019年3月25日
*/
public class SpringUtils {
private static ApplicationContext applicationContext;
public static void setApplicationContext(ApplicationContext applicationContext) {
SpringUtils.applicationContext = applicationContext;
}
public static ApplicationContext getApplicationContext() {
return SpringUtils.applicationContext;
}
}
4、编写一个创建线程池的类
package com.glanway.zpparts.test;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* 创建线程池
* @author zp_ww
* @date 2019年3月25日
*/
public class ThreadPoolHelper {
private static ThreadPoolExecutor threadPoolExecutor;
static {
// 设置线程池同时进行的线程数、创建的线程数、失效时间
threadPoolExecutor = new ThreadPoolExecutor(5, 10, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
}
public static void execute(Runnable runnable) {
threadPoolExecutor.execute(runnable);
}
}
5、创建一个正确数据跑的线程方法
package com.glanway.zpparts.test;
import java.util.List;
import org.apache.poi.ss.usermodel.Row;
import org.springframework.context.ApplicationContext;
import com.glanway.zpparts.service.wyyx.WyYxUserService;
/**
* 正确线程实现类
* @author zp_ww
* @date 2019年3月25日
*/
public class ExcelTask implements Runnable {
//开始索引
private int startIndex;
//处理的条数
private int total;
//sheet
private List<Row> row;
public ExcelTask(List<Row> row, int startIndex, int total) {
this.startIndex = startIndex;
this.row = row;
this.total = total;
}
/**
* 线程的实现方法
*/
@Override
public void run() {
//WyYxUserService wyyxUserService = SpringUtils.getBean(WyYxUserService.class);
//WyyxUser user = wyyxUserService.getWyYxUserByMemberId(Long.valueOf(16));
//ZppartsServiceUtilTwo.getService();
ApplicationContext applicationContext = SpringUtils.getApplicationContext();
// 获取service
WyYxUserService wyYxUserService = applicationContext.getBean(WyYxUserService.class);
System.out.println(wyYxUserService);
System.out.println(wyYxUserService.getWyYxUserByMemberId(Long.valueOf(16)));
// WyyxUser user = ZppartsServiceUtils.getZppartsServiceUtils().getWyYxUserService().getWyYxUserByMemberId(Long.valueOf(16));
// System.out.println(user.getName());
// System.out.println(Thread.currentThread().getName() + " 处理成功数据:"+startIndex + ":" + (startIndex + total));
// for (int i = startIndex; i < total; i++) {
//
// }
}
public int getStartIndex() {
return startIndex;
}
public void setStartIndex(int startIndex) {
this.startIndex = startIndex;
}
public int getTotal() {
return total;
}
public void setTotal(int total) {
this.total = total;
}
public List<Row> getRow() {
return row;
}
public void setRow(List<Row> row) {
this.row = row;
}
}
6、创建一个错误数据跑的线程实现类
package com.glanway.zpparts.test;
import java.util.List;
import org.apache.poi.ss.usermodel.Row;
/**
* 错误数据线程实现类
* @author zp_ww
* @date 2019年3月25日
*/
public class ExcelErrorTask implements Runnable {
//sheet
private List<Row> row;
public ExcelErrorTask(List<Row> row) {
this.row = row;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " 处理失败数据:" + row.size());
}
public List<Row> getRow() {
return row;
}
public void setRow(List<Row> row) {
this.row = row;
}
}
7、编写一个测试类
package com.glanway.zpparts.test;
import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
/**
* 线程测试
* @author zp_ww
* @date 2019年3月25日
*/
public class ExcelUpload {
public static List<Row> resultList = new ArrayList<>();
public static List<Row> errorList = new ArrayList<>();
public static void test() throws Exception {
long startTime = System.currentTimeMillis();
Set<String> heavySet = new HashSet<String>();
int lastSize = 0;
File file =
new File("C:/Users/zp_ww/Documents/WeChat Files/Files/数据/数据", "商品导入测试.xlsx");
FileInputStream inputStream = new FileInputStream(file);
XSSFWorkbook workbook = new XSSFWorkbook(inputStream);
System.out.println("读取文件耗时: " + (System.currentTimeMillis() - startTime));
Sheet sheet = workbook.getSheetAt(0);
int rowNumber = sheet.getLastRowNum(); // 第一行从0开始算
for (int i = 1; i <= rowNumber; i++) {
Row row = sheet.getRow(i);
row.getCell(4).setCellType(Cell.CELL_TYPE_STRING);
row.getCell(7).setCellType(Cell.CELL_TYPE_STRING);
String stringCellValue = row.getCell(4).getStringCellValue().replace(" ", "");
String stringCellValue2 = row.getCell(7).getStringCellValue().replace(" ", "");
heavySet.add(stringCellValue + stringCellValue2);
if (heavySet.size() == lastSize) {
// 插入失敗
errorList.add(row);
} else {
// 插入成功
resultList.add(row);
lastSize = heavySet.size();
}
}
System.out.println("文件去重耗时: " + (System.currentTimeMillis() - startTime));
int resultListSize = resultList.size();
// 每个线程最低执行的行数
int count = (int)(resultListSize / 5);
// 多余的行数
int num = resultListSize - (count * 5);
for (int i = 0; i < 5; i++) {
if (i == 4) {
// 创建一个线程
ThreadPoolHelper.execute(new ExcelTask(resultList, count * i, count + num));
} else {
ThreadPoolHelper.execute(new ExcelTask(resultList, count * i, count));
}
}
ThreadPoolHelper.execute(new ExcelErrorTask(errorList));
}
}