最近做了一个功能模块,就是有大量的文本文件,需要录入数据库,之前的逻辑是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()+"完成"); } } }