Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/main/java/com/github/hcsp/multithread/1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
I am a teacher
I am a person
1
3 changes: 3 additions & 0 deletions src/main/java/com/github/hcsp/multithread/2.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
I am a teacher
I am a person
2
3 changes: 3 additions & 0 deletions src/main/java/com/github/hcsp/multithread/3.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
I am a teacher
I am a person
3
3 changes: 3 additions & 0 deletions src/main/java/com/github/hcsp/multithread/4.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
I am a teacher
I am a person
4
3 changes: 3 additions & 0 deletions src/main/java/com/github/hcsp/multithread/5.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
I am a teacher
I am a person
5
3 changes: 3 additions & 0 deletions src/main/java/com/github/hcsp/multithread/6.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
I am a teacher
I am a person
6
Original file line number Diff line number Diff line change
@@ -1,12 +1,76 @@
package com.github.hcsp.multithread;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

不应使用 '.*' 形式的导入 - java.util.concurrent.* 。


public class MultiThreadWordCount1 {
// 使用threadNum个线程,并发统计文件中各单词的数量
public static Map<String, Integer> count(int threadNum, List<File> files) {
return null;
// 使用线程池
public static Map<String, Integer> count(int threadNum, List<File> files) throws FileNotFoundException, ExecutionException, InterruptedException {
List<Future<Map<String, Integer>>> resultsFuture = new ArrayList<>();
ExecutorService threadPool = Executors.newFixedThreadPool(threadNum);
for (File file : files) {
BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
Future<Map<String, Integer>> mapFuture = threadPool.submit(new readFileCallable(bufferedReader));
resultsFuture.add(mapFuture);
}
threadPool.shutdown();
return mergeCountResults(resultsFuture);
}

private static Map<String, Integer> mergeCountResults(List<Future<Map<String, Integer>>> resultsFuture) throws ExecutionException, InterruptedException {
Map<String, Integer> finalResults = new HashMap<>();
for (Future<Map<String, Integer>> mapFuture : resultsFuture) {
Map<String, Integer> stringIntegerMap = mapFuture.get();
for (Map.Entry<String, Integer> stringIntegerEntry : stringIntegerMap.entrySet()) {
String word = stringIntegerEntry.getKey();
int updatedValue = finalResults.getOrDefault(word, 0) + stringIntegerEntry.getValue();
finalResults.put(word, updatedValue);
}
}
return finalResults;
}

public static class readFileCallable implements Callable<Map<String, Integer>> {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

名称 'readFileCallable' 必须匹配表达式: '^[A-Z一-鿿][a-zA-Z0-9一-鿿]*$' 。

BufferedReader bufferedReader;

public readFileCallable(BufferedReader bufferedReader) {
this.bufferedReader = bufferedReader;
}

@Override
public Map<String, Integer> call() throws Exception {
Map<String, Integer> fileWords = new HashMap<>();
String line;
while ((line = bufferedReader.readLine()) != null) {
String[] words = line.split(" ");
for (String word : words) {
fileWords.put(word, fileWords.getOrDefault(word, 0) + 1);
}
}
return fileWords;
}
}

public static void main(String[] args) throws FileNotFoundException, ExecutionException, InterruptedException {
List<File> files = new ArrayList<>();
files.add(new File("D:\\project\\multithread-word-count\\src\\main\\java\\com\\github\\hcsp\\multithread\\1.txt"));
files.add(new File("D:\\project\\multithread-word-count\\src\\main\\java\\com\\github\\hcsp\\multithread\\2.txt"));
files.add(new File("D:\\project\\multithread-word-count\\src\\main\\java\\com\\github\\hcsp\\multithread\\3.txt"));
files.add(new File("D:\\project\\multithread-word-count\\src\\main\\java\\com\\github\\hcsp\\multithread\\4.txt"));
files.add(new File("D:\\project\\multithread-word-count\\src\\main\\java\\com\\github\\hcsp\\multithread\\5.txt"));
files.add(new File("D:\\project\\multithread-word-count\\src\\main\\java\\com\\github\\hcsp\\multithread\\6.txt"));
Map<String, Integer> results = MultiThreadWordCount1.count(5, files);
for (Map.Entry<String, Integer> resultEntry : results.entrySet()) {
System.out.println("Key: " + resultEntry.getKey()+" Value: " + resultEntry.getValue());
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'+' 后应有空格。
'+' 前应有空格。

}
}
}

Original file line number Diff line number Diff line change
@@ -1,8 +1,85 @@
package com.github.hcsp.multithread;

import java.io.*;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

不应使用 '.*' 形式的导入 - java.io.* 。

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;

public class MultiThreadWordCount2 {
// 使用threadNum个线程,并发统计文件中各单词的数量
// public static Map<String, Integer> count(int threadNum, List<File> files) {
// return null;
// }
// 使用ForkJoinPool
public static Map<String, Integer> count(int threadNum, List<File> files) {
ForkJoinPool forkJoinPool = new ForkJoinPool(threadNum);
ForkJoinTask<Map<String, Integer>> task = new readFileWordTask(files);
return forkJoinPool.invoke(task);
}

public static class readFileWordTask extends RecursiveTask<Map<String, Integer>> {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

名称 'readFileWordTask' 必须匹配表达式: '^[A-Z一-鿿][a-zA-Z0-9一-鿿]*$' 。

private static final int THRESHOLD = 5;
List<File> files;

public readFileWordTask(List<File> files) {
this.files = files;
}

@Override
protected Map<String, Integer> compute() {
Map<String, Integer> results = null;
if (files.size() < THRESHOLD) {
for (File file : files) {
try {
BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
results = new ConcurrentHashMap<>();
String line;
while ((line = bufferedReader.readLine()) != null) {
String[] words = line.split(" ");
for (String word : words) {
results.put(word, results.getOrDefault(word, 0) + 1);
}
}
System.out.println(file.getCanonicalFile());
} catch (IOException e) {
e.printStackTrace();
}
}
} else {
List<File> subFiles1 = files.subList(0, files.size() / 2);
List<File> subFiles2 = files.subList(files.size() / 2, files.size());
readFileWordTask subTask1 = new readFileWordTask(subFiles1);
readFileWordTask subTask2 = new readFileWordTask(subFiles2);
invokeAll(subTask1, subTask2);
Map<String, Integer> subResult1 = subTask1.join();
Map<String, Integer> subResult2 = subTask2.join();
results = mergeTwoMap(subResult1, subResult2);
}
return results;
}

private Map<String, Integer> mergeTwoMap(Map<String, Integer> subResult1, Map<String, Integer> subResult2) {
Map<String, Integer> results = new ConcurrentHashMap<>(subResult1);
for (Map.Entry<String, Integer> stringIntegerEntry : subResult2.entrySet()) {
String word = stringIntegerEntry.getKey();
results.put(word, subResult2.getOrDefault(word, 0) + 1);
}
return results;
}
}

public static void main(String[] args) throws IOException {
List<File> files = new ArrayList<>();
files.add(new File("D:\\project\\multithread-word-count\\src\\main\\java\\com\\github\\hcsp\\multithread\\1.txt"));
files.add(new File("D:\\project\\multithread-word-count\\src\\main\\java\\com\\github\\hcsp\\multithread\\2.txt"));
files.add(new File("D:\\project\\multithread-word-count\\src\\main\\java\\com\\github\\hcsp\\multithread\\3.txt"));
files.add(new File("D:\\project\\multithread-word-count\\src\\main\\java\\com\\github\\hcsp\\multithread\\4.txt"));
files.add(new File("D:\\project\\multithread-word-count\\src\\main\\java\\com\\github\\hcsp\\multithread\\5.txt"));
files.add(new File("D:\\project\\multithread-word-count\\src\\main\\java\\com\\github\\hcsp\\multithread\\6.txt"));
Map<String, Integer> results = MultiThreadWordCount2.count(5, files);
for (Map.Entry<String, Integer> resultEntry : results.entrySet()) {
System.out.println("Key: " + resultEntry.getKey()+" Value: " + resultEntry.getValue());
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'+' 后应有空格。
'+' 前应有空格。

}
}
}