zoukankan      html  css  js  c++  java
  • 多线程实现多文件的录入

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

      

  • 相关阅读:
    剑指offer_24:二叉树中和为某一值的路径
    剑指offer_23:二叉搜索树的后序遍历序列
    Java基础类型大小
    旋转数组
    剑指offer_22:从上往下打印二叉树
    剑指offer_21:栈的压入、弹出序列
    剑指offer_20:包含min函数的栈
    剑指offer_19:顺时针打印矩阵
    剑指offer_18:二叉树的镜像
    redis jedis源码
  • 原文地址:https://www.cnblogs.com/donghb/p/7908521.html
Copyright © 2011-2022 走看看