一、WordCount需求
输处一个文件中每个不同的单词以及它的重复次数,并记录程序执行时间
如果在处理数据的过程中如果遇到文本量巨大的数据如何处理(多线程)
二、单线程版WordCount
思路以及具体代码:
大概思路:记录开始时间在结束时记录结束时间,用FileReader和BufferedReader读取文本文件,用split()方法将文本内容拆分为每一个单词,利用Map的特性,key记录单词,value记录重复次数,第一次出现就设置value为1
这里是定义和初始化要用到的相关内容
通过输入流读文件,再定义临时string变量,用while循环读取
根据空格将文件拆分为具体的单词的数组,判断splitStr[i]是否在定义的map中如果在,就更具splitStr[i]找到他的value值,将它加一,如果不在说明是第一次出现,设置它的value值为1
foreach遍历吧key值即具体单词和value值即出现次数拿出来,输出,最后记录结束时间,相减得到运行时间
三、多线程版WordCount
思路以及具体代码:
大致思路;其他和前者一样就是将每一行文字拼接起来,当行数到达设定的值时,分配一个线程,在线程run()方法中运行对这一串内容的拆分计数等操作,然后用StringBuffer的delete()方法清空,重新记录后面的内容,这样我们在主线程只需处理因不满分配而没被处理的文本就可以,这样可以多线程并行,提高运行效率,最后在主线程设置一个静态的总map(threadMap),key值记录线程名称,value值记录线程跑出来的map,最后判断程序是否执行结束,如果结束就通过key-value的层层对饮关系找到每个单词和出现次数
因为多个线程需要共享数据,所以用继承Runnable的方式创建一个Thread类,重写这个类的run()方法,定义map记录这个线程处理的单词和出现次数的结果,自定义构造方法需要传入需要处理的数据
定义输入流对象,行数和线程池,通过线程池管理运行Thread,也方便后面判断所有线程是否结束
输入流读文件,StringBuffer临时变量用appen()方法记录内容,当读的行数到达100000行就分配线程处理,清空临时变量的数据,总Map记录key记录线程名,value记录该线程记录的Map
处理余下的不足100000行的数据
处理完关闭线程池,判断是否关闭结束,true就执行接下来的操作
定义一个mapResult的map作为所有单词数据的总结果
用keySet()方法加foreach遍历threadMap得到所有的key(线程名),用变量key记录
(以下这些是在foreach中进行的--------------------------------)
通过get()方法填入key得到所有的value值(即线程池分配的每一个线程加额外不足100000条数据得到的map),该map记录了各自线程记录的数据(单词和出现次数)
在用keySet()获得该map的key(即每一个不同的单词),用word记录,通过迭代器遍历得到value(即每个单词出现的次数),
再把这些单词判断是否在mapResult中,不在就把该单词用put()方法放入并记录次数(他在该线程中记录到的次数),存在就把存在的次数+该线程中出现的次数
(以上这些是在foreach中进行的--------------------------------)
最后赋值个变量输出结果
输出运行时长
四、 单线程与多线程运行比较
当数据量较多时,多线程运行效率更高
单线程:
多线程:
当数据量叫小时单线程更占优