使用Future 实现多线程的文件读取功能实现

    以往我们实现多线程的方式莫非继承Thread类、或者实现Runnable方法。这种实现的方式过于复杂,没有很深的理解很难掌握。其中的成本是较高的;

无意中看到有使用Future 实现多线程的案例;便进行简单研究并记录下来;

本文的案例场景如下:D盘有200个文件,希望以多线程的方式快速读取并进行分析数据;

首先思考一个问题:什么地方需要多线程处理?

多线程的处理好处就是 不等待 主线程继续执行其他方法;

那么读取文件最为耗时的,所以我们需要将读取文件这个步骤抽取出来 使用多线程方式实现;


那么首先写实现Callable接口的类FileCallable 

主要功能:1、实现主线程给子线程进行参数传递

                2、实现读取文件功能

                3、读取文件内容并封装成ArrayList<databaen> ;



class FileCallable implements Callable< ArrayList<databaen>>{
	private String Filename;
	private String filepath;
	FileCallable(){};
	
	public FileCallable(String filepath) {
		this.filepath = filepath;
	}
	ArrayList<databaen> datab = new ArrayList<databaen>();
	@Override
	public ArrayList<databaen> call() throws Exception {
		
		datab = new ArrayList<databaen>();
		File file = new File(filepath);
		List<String> list = FileUtils.readLines(file, "utf-8");
		int size = list.size() - 13;
		for (int i = 13; i < list.size(); i++) {
			String al = list.get(i);
			if (al.indexOf("#") > -1) {
				size--;
				continue;
			} else if (al.indexOf("2018") == 0) {

				getstrsz(al);
			} else {
				continue;
			}

		}
		list = null;
		return datab;


		
	}
	
	}

那么干活的人已经有了FileCallable 、下面需要给干活的人造点房子(ExecutorService )让他们好好的干活了,

并且让他们把干活的结果放进我们的仓库(List<Future> )中;

详解源码:ExecutorService ExecutorService=  Executors.newFixedThreadPool(5);

为我们的读取的文件的线程创建一个5个线程池;

List<Future> list = new ArrayList<Future>(); 为我们的每一个线程创建一个Future对象来接受劳动果实;

FileCallable FileCallable = new FileCallable(string,FileFactoryReadimp.getfilename(string));

//实例化我的工人将程序必要的参数传递给工人(告诉他文件名称路径是什么)

Future<ArrayList<databaen>> submit = ExecutorService.submit(FileCallable);

//将工人程序提交到线程池中并返回一个 Future<ArrayList<databaen>>   也就是执行的结果

list.add(submit);

//将执行的结果加入list 仓库中后期只要遍历list就能获取所有的劳动果实;



public static void main(String[] args) throws InterruptedException, ExecutionException {
		
		
		FileFactoryReadimp FileFactoryReadimp = new FileFactoryReadimp();
		//获取文件列表
		
		String path = "D://bridgetestdemo";// 定义文件路径
		ArrayList<String> filelist = FileFactoryReadimp.getfilenames(path);
		
		ExecutorService ExecutorService=  Executors.newFixedThreadPool(5);
		List<Future> list = new ArrayList<Future>();
		for (int i = 0; i < filelist.size(); i++) {
			
			String string = filelist.get(i).toString();
			System.out.println(string);
			FileCallable FileCallable = new FileCallable(string,FileFactoryReadimp.getfilename(string));
			Future<ArrayList<databaen>> submit = ExecutorService.submit(FileCallable);
			list.add(submit);
			
		}
		ExecutorService.shutdown();
		
		for (Future future : list) {
			ArrayList<databaen> x = (ArrayList<databaen>) future.get();
			for (int i = 0; i < x.size(); i++) {
				databaen databaen = x.get(i);
				System.out.println(databaen.toString());
				
				
			}
			 x.clear();
		}
		
	
	}
	
	
	
}
3个线程读取
--------------
Mon Jun 11 14:45:35 CST 2018


Mon Jun 11 14:47:11 CST 2018
5个线程读取
----------------------------
Mon Jun 11 14:48:13 CST 2018

Mon Jun 11 14:49:38 CST 2018
6个线程读取
----------------------------
Mon Jun 11 14:55:41 CST 2018


Mon Jun 11 14:57:12 CST 2018

结果也是比较喜人的;2G的文件读取只需要3分钟左右就完成了

之前单线程读取大约需要20分钟;


猜你喜欢

转载自blog.csdn.net/qq_19239339/article/details/80652864