给一个多行的txt文本文件,统计里面每个单词出现多少次(如下图)
单线程代码:
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.TreeMap;
public class TestDemo {
public static void main(String[] args) {
FileReader fr = null;
BufferedReader br = null;
TreeMap<String, Integer> worldMap = new TreeMap<String, Integer>();
long start = System.currentTimeMillis();
try {
fr = new FileReader("fos.txt");
br = new BufferedReader(fr);
String temp = "";
int num = 0;//读取行数
while ((temp = br.readLine()) != null) {
num++;
String[] splitStr = temp.trim().split(" ");
for (int i = 0; i < splitStr.length; i++) {
if (worldMap.containsKey(splitStr[i])) {//原Map中包含key
Integer count = worldMap.get(splitStr[i]) + 1;
worldMap.put(splitStr[i], count);
} else {
//原map中不包含这个key(单词)
worldMap.put(splitStr[i], 1);
// System.out.println("不包含");
}
}
}
System.out.println("读取文件总行数:" + num);
for (String key : worldMap.keySet()) {
Integer wordNum = worldMap.get(key);
System.out.println(key + "出现的次数为:" + wordNum);
}
long totalTime = System.currentTimeMillis() - start;
System.out.println("程序运行时间:" + totalTime);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
br.close();
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
运行结果:
多线程代码:
import java.util.HashMap;
import java.util.Map;
public class wordCount implements Runnable {
String content = "";
Map<String, Integer> map = new HashMap<>();
public wordCount(String content) {
this.content = content;
}
@Override
public void run() {
String[] split = content.trim().split(" ");
for (int i = 0; i < split.length; i++) {
if (map.containsKey(split[i])){
Integer value = map.get(split[i]) + 1;
map.put(split[i],value);
}else {
map.put(split[i],1);
}
}
}
}
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class wordCountTest {
static Map<String, Map<String, Integer>> threadMAP = new HashMap<>();
public static void main(String[] args) {
long start = System.currentTimeMillis();
FileReader fr = null;
BufferedReader bf = null;
int lineNum = 0;
ExecutorService executorService = Executors.newCachedThreadPool();
try {
fr = new FileReader("fos.txt");
bf = new BufferedReader(fr);
StringBuffer listStrBuf = new StringBuffer("");
String lineStr = "";
// boolean tag = true;
while ((lineStr = bf.readLine()) != null) {
listStrBuf.append(lineStr + " ");
lineNum++;
if (lineNum % 100000 == 0) {
wordCount wordCount = new wordCount(listStrBuf.toString());
listStrBuf.delete(0, listStrBuf.length());
Thread thread = new Thread(wordCount);
// thread.start();
executorService.execute(thread);
threadMAP.put("thread-" + lineNum / 100000, wordCount.map);
}
}
if (listStrBuf.toString().length() > 0) {
wordCount wordCount = new wordCount(listStrBuf.toString());
Thread thread = new Thread(wordCount);
executorService.execute(thread);
threadMAP.put("thread-last", wordCount.map);
}
System.out.println("文件总行数为:" + lineNum);
executorService.shutdown();
while (true) {
if (executorService.isTerminated()) {
Map<String, Integer> mapResult = new HashMap<>();
// for (Map<String, Integer> tempMap : threadMAP.values()) {
// System.out.println(tempMap.keySet());
// }
for (String key : //thread-1 thread-2 ....... thread-last
threadMAP.keySet()) {
Map<String, Integer> perThreadWorldNum = threadMAP.get(key);
Set<String> perThreadWords = perThreadWorldNum.keySet();
Iterator<String> iterator = perThreadWords.iterator();
while (iterator.hasNext()) {
String word = iterator.next();
if (mapResult.containsKey(word)) {
Integer wordsNum = perThreadWorldNum.get(word);
Integer haveNum = mapResult.get(word);
mapResult.put(word, wordsNum + haveNum);
} else {
mapResult.put(word, perThreadWorldNum.get(word));
}
}
/*
System.out.println(key);
System.out.println(threadMAP.get(key).keySet());
for (String word :
threadMAP.get(key).keySet()) {
System.out.print(word + ":" + threadMAP.get(key).get(word) + " ");
}
System.out.println();*/
}
Set<String> resultWords = mapResult.keySet();
for (String word : resultWords) {
System.out.println(word + " : " + mapResult.get(word));
}
break;
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fr.close();
bf.close();
} catch (IOException e) {
e.printStackTrace();
}
}
long endTime = System.currentTimeMillis() - start;
System.out.println("程序运行时长:" + endTime + "ms");
}
运行结果:
总结:
两次运行结果比较:TXT文件总行数33082行,单线程运行时间39ms,多线程运行时间45ms
后面又测试了一个595476行的txt文件,单线程运行时间208ms,多线程运行时间182ms
所以说,并不是多线程运行的时间一定会比单线程运行的时间短。
但是,当文件比较大的时候多线程的优势就体现出来了。
单线程和多线程在选用的时候要看具体需求。