最近做了一个功能模块,就是有大量的文本文件,需要录入数据库,之前的逻辑是for循环实现的,所以当文件非常多的时候,就会非常吃力,而且效率低,所以就想到了用线程池来解决这个问题。首先,我们的思路是,先判断有多少个文件,如果10个文件一下,那单线程就可以解决,没必要开多个线程。10个到100个文件,我们就可以开10个线程来处理这些任务,100个文件以上,就开100个线程。废话不多说,直接上代码。
1.创建线程
public static void main(String[] args) throws Exception {
ApplicationContext ac = new ClassPathXmlApplicationContext("conf/spring-config.xml");
ReaderMapper readermapper = ac.getBean(ReaderMapper.class);
//查询出所有等待读取文件
List<FileName> f_list = readermapper.selectTxt();
int f_size = f_list.size();//文件数目
if(f_size>=1 && f_size<10){
ExecutorService pool = Executors.newSingleThreadExecutor(); //创建单线程池
MyRunnable1 t1 = new MyRunnable1(f_list, 0, f_size);
pool.submit(t1);
pool.shutdown(); //结束线程池
}else if(f_size>=10 && f_size<100){
ExecutorService pool = Executors.newFixedThreadPool(10); //创建线程池
//取余,把余数给最后一个线程
int m = f_list.size()%10;
//每个线程分配多少个任务
int s = (f_list.size()-m)/10;
//创建前九个个线程
for(int i = 0; i < 9; i++){
MyRunnable1 t1 = new MyRunnable1(f_list, s*i, s*(i+1));
pool.submit(t1);
}
//创建第10个线程
MyRunnable1 t2 = new MyRunnable1(f_list, s*9, s*10+m);
pool.submit(t2);
pool.shutdown(); //结束线程池
}else if(f_size>=100){
ExecutorService pool = Executors.newFixedThreadPool(100); //创建线程池
//取余,把余数给最后一个线程
int m = f_list.size()%100;
//每个线程分配多少个任务
int s = (f_list.size()-m)/100;
//创建前99个个线程
for(int i = 0; i < 99; i++){
MyRunnable1 t1 = new MyRunnable1(f_list, s*i, s*(i+1));
pool.submit(t1);
}
//创建第100个线程
MyRunnable1 t2 = new MyRunnable1(f_list, s*99, s*100+m);
pool.submit(t2);
pool.shutdown(); //结束线程池
}
}
2.执行相应的线程
为了保证各个任务不冲突,我的逻辑是,给他们每个线程分配对应的任务,然后各自执行自己的,从查出来list 中,读取自己对应的起始位置。
public class MyRunnable1 implements Runnable {
private List<FileName> f_list;
private int start;
private int end;
public MyRunnable1(List<FileName> f_List, int start, int end){
super();
this.f_list = f_List;
this.start = start;
this.end = end;
}
public void run() {
ApplicationContext ac = new ClassPathXmlApplicationContext("conf/spring-config.xml");
ReaderMapper readermapper = ac.getBean(ReaderMapper.class);
//执行任务
for (int n = this.start; n <this.end; n++){
//创建流
File file = new File(f_list.get(n).getPath1());
BufferedReader bufr = null;
FileReader fr;
String line = null;
String[] name = null;// 定义当前行String数组
File_test ft = new File_test();
int lineCount = 0; //计数器,统计行数
if(file.isFile()){
try {
fr = new FileReader(file);
bufr = new BufferedReader(fr);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
while((line = bufr.readLine()) != null){
name = line.split("##");
lineCount++;//计数器,统计行数
// 上传文件解析不正确,可能为数据不全
if (name.length != 3) {
//报错时候修改状态
readermapper.updateState(f_list.get(n).getPath1());
System.err.println("文件 "+f_list.get(n).getName() +"第"+lineCount+"行出错了!!" );
break;
}else{
ft.setOne(name[0]);
ft.setTwo(name[1]);
ft.setThree(name[2]);
ft.setTextname(f_list.get(n).getPath1());
//信息加入另一个表
readermapper.insert(ft);
//修改读取状态
readermapper.updateTxt(f_list.get(n).getPath1());
}
}
} catch (IOException e) {
e.printStackTrace();
}
try {
bufr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println("任务"+Thread.currentThread().getName()+"完成");
}
}
}