您的位置:首页 > 其它

使用多线程优化批量导入的回显功能

2017-12-21 15:41 676 查看
最近参与开发的项目有批量导入数据的功能,导入回显的过程中需要做一些校验,以确保导入数据的正确性。如果导入的数据特别多,校验规则也特别多,那么一条一条校验的时间就会很长,影响系统使用。这个时候可以使用多线程来并行校验。这里记录一下,以防忘掉。

一般要导入的每一条数据的校验都是相互独立的,那么让几条数据并行校验不会影响其他数据。基于这个思想,使用多线程优化导入。

笔者所在项目使用了SSM框架,代码实现是在service层(这里只是基于本人的工作环境而这样写,如果不是这样的环境,实现思想也是一样的。)

实现如下:

(1)新建一个ImportServiceImpl.java类,里面创建一个回显方法ehcoImportInfo()方法,和一个内部类ThreadParallel,实现Callable接口(如果没有返回值,也可以实现Runnable接口)。

public class ImportServiceImpl  {
//内部类(线程类)
private class ThreadParallel implements Callable<Object>{
//内部类无参构造方法,如果需要传递参数来启动线程,则定义相应的有参构造方法
public ThreadParallel() {
}
@Override
public Object call() throws Exception {
//具体的校验代码放在这里处理
return null;
}
//回显方法
public void ehcoImportInfo() {
//这个方法里面将调用内部类ThreadParallel
}
}


(2)在这个ehcoImportInfo方法中使用这个内部类。

public void ehcoImportInfo() {
int listSize = 3000; // 导入3000条数据
// 根据导入的数据量确定启动线程的个数(根据实际情况来确定)
int threadNum = 0; // 记录线程数量
if (listSize > 0 && listSize < 100) {
threadNum = 1;
} else {
if (listSize >= 1000 && listSize <= 3000) {
threadNum = 10;
} else {
if ((listSize % 100) == 0) {
threadNum = listSize / 100;
} else {
threadNum = listSize / 100 + 1;
}
}
}

List<Object> subList; // 存放一个范围内的导入数据
int count =1; // 行号
// 存放所有分割的数据
Map<Integer, Object> map = new HashMap<Integer, Object>();
// 分割导入的数据
for (int i = 0; i < threadNum; i++) {
subList= new ArrayList<Object>();
for (int j = (listSize/threadNum)*(count-1); j < (listSize/threadNum)*count; j++) {
mList.add(list.get(j));
}
map.put(i, mList);
count ++;
}
// 存放线程返回值
List<Future> futureList = new ArrayList<Future>();
ExecutorService executorService = Executors.newFixedThreadPool(threadNum); // 创建线程池
// 创建线程,并启动线程(这是关键,这里面创建了内部线程类的对象,里面传的参数,根据实际情况决定,相应的内部类中也要有对应的构造方法。利用submit可以启动线程,)
for (int x = 0; x < map.size(); x++) {
futureList.add(executorService.submit(new ThreadParallel(map.get(x),(listSize/threadNum)*x + 1)));
}
executorService.shutdown(); // 关闭线程池
// 拼接提示信息
for (Future future : futureList) {
try {
System.out.println(future.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}


这只是大致的结构,代码并不完整,主要是理解这种思想和做法。总结一下:就是在方法中使用内部线程类,将大批量数据划分成小批量数据,然后每一个小批量数据启用一个线程并行运行,然后再汇总结果(不需要返回值的就不用处理结果了),这样可以成倍地降低校验时间。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐