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

  

posted on 2017-11-28 11:01  donghongbo  阅读(1645)  评论(1编辑  收藏  举报