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: 0 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,6 @@
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
<configuration>

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.

这里为什么要去掉?

<argLine>-Dfile.encoding=UTF-8</argLine>
</configuration>
</plugin>
<plugin>
<artifactId>maven-checkstyle-plugin</artifactId>
Expand Down
52 changes: 52 additions & 0 deletions src/main/java/com/github/hcsp/multithread/FileDetector.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.github.hcsp.multithread;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;

public class FileDetector extends Thread {

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.

名字取的不好,明明是读文件的,为啥叫Detector?我看了这个名字的第一反应是用来检测文件是不是存在的。

List<Map<String, Integer>> result;
Object object;
File file;
CountDownLatch countDownLatch;

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.

这个CountDownLatch到处都没用到,那它为什么存在?


public FileDetector(List<Map<String, Integer>> countResults, Object object, File file) {
result = countResults;
this.object = object;
this.file = file;
}

public FileDetector(List<Map<String, Integer>> result, Object object, File file, CountDownLatch countDownLatch) {
this.result = result;
this.object = object;
this.file = file;
this.countDownLatch = countDownLatch;
}

@Override
public void run() {
System.out.println("子线程:" + Thread.currentThread().getName() + "执行");
Map<String, Integer> myCountResult = new HashMap<>();
try (BufferedReader bufferedReader = new BufferedReader(new FileReader(file));) {
String line = "";
while ((line = bufferedReader.readLine()) != null) {
String[] split = line.split(" ");
for (String word : split) {
if (myCountResult.containsKey(word)) {
myCountResult.put(word, myCountResult.get(word) + 1);
} else {
myCountResult.put(word, 1);
}
}
}
result.add(myCountResult);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,54 @@
package com.github.hcsp.multithread;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

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 ExecutionException, InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(threadNum);
Map<String, Integer> countResult = new HashMap<>();
List<Future<Map<String, Integer>>> futures = new ArrayList<>();
for (File file : files) {
futures.add(executorService.submit(() -> {
Map<String, Integer> result = new HashMap<>();
BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
String line = "";
while ((line = bufferedReader.readLine()) != null) {
String[] split = line.split(" ");
for (String word : split) {
if (result.containsKey(word)) {
result.put(word, result.get(word) + 1);
} else {
result.put(word, 1);
}
}
}
return result;
}));
}
Map<String, Integer> waitforMerge;
for (Future<Map<String, Integer>> future : futures) {
waitforMerge = future.get();
mergeResulttoFinal(waitforMerge, countResult);
}
return countResult;
}

private static void mergeResulttoFinal(Map<String, Integer> waitforMerge, Map<String, Integer> countResult) {

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.

Suggested change
private static void mergeResulttoFinal(Map<String, Integer> waitforMerge, Map<String, Integer> countResult) {
private static void mergeResultToFinal(Map<String, Integer> waitForMerge, Map<String, Integer> countResult) {

for (Map.Entry<String, Integer> entry : waitforMerge.entrySet()) {
String word = entry.getKey();
int i = countResult.getOrDefault(word, 0) + entry.getValue();
countResult.put(word, i);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,38 @@
package com.github.hcsp.multithread;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class MultiThreadWordCount2 {
// 使用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 InterruptedException {
List<Map<String, Integer>> results = new ArrayList<>();
Map<String, Integer> countResult = new HashMap<>();
buildDetector(threadNum, files, results);
Thread.sleep(100);

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.

你怎么知道sleep 100毫秒就足够其他线程完成工作?

for (Map<String, Integer> waitforMerge : results) {
mergeResulttoFinal(waitforMerge, countResult);
}
return countResult;
}

private static void buildDetector(int threadNum, List<File> files, List<Map<String, Integer>> results) {
for (int i = 0; i < threadNum; i++) {
new FileDetector(results, null, files.get(i)).start();
}
}

private static void mergeResulttoFinal(Map<String, Integer> waitforMerge, Map<String, Integer> countResult) {
for (Map.Entry<String, Integer> entry : waitforMerge.entrySet()) {
String word = entry.getKey();
int i = countResult.getOrDefault(word, 0) + entry.getValue();
countResult.put(word, i);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,39 @@
package com.github.hcsp.multithread;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;

public class MultiThreadWordCount3 {
// 使用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 InterruptedException {
final CountDownLatch countDownLatch = new CountDownLatch(threadNum);
List<Map<String, Integer>> results = new ArrayList<>();
Map<String, Integer> countResult = new HashMap<>();
buildDetector(threadNum, files, results, countDownLatch);

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.

我觉得你这里少了countDownLatch.await().

for (Map<String, Integer> waitforMerge : results) {
mergeResulttoFinal(waitforMerge, countResult);
}
return countResult;
}

private static void buildDetector(int threadNum, List<File> files, List<Map<String, Integer>> results, CountDownLatch countDownLatch) {
for (int i = 0; i < threadNum; i++) {
new FileDetector(results, null, files.get(i), countDownLatch).start();

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.

CountDownLatch在FileDetector里根本没用到,那传递进去干什么?

}
}

private static void mergeResulttoFinal(Map<String, Integer> waitforMerge, Map<String, Integer> countResult) {
for (Map.Entry<String, Integer> entry : waitforMerge.entrySet()) {
String word = entry.getKey();
int i = countResult.getOrDefault(word, 0) + entry.getValue();
countResult.put(word, i);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,38 @@
package com.github.hcsp.multithread;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class MultiThreadWordCount4 {
// 使用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 InterruptedException {
List<Map<String, Integer>> results = new ArrayList<>();
Map<String, Integer> countResult = new HashMap<>();
buildDetector(threadNum, files, results);
Thread.sleep(100);

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.

同上,为什么100毫秒就够了?假如正在处理的是很大的文件,100毫秒处理不完怎么办?这种拍脑袋的代码(“我猜100毫秒就够了”)请尽量少写。你需要的是正确的线程同步的方法,比如CountDownLatch,但是上面明明创建了CountDownLatch准备用,又没用到,我很迷惑不解。

for (Map<String, Integer> waitforMerge : results) {
mergeResulttoFinal(waitforMerge, countResult);
}
return countResult;
}

private static void buildDetector(int threadNum, List<File> files, List<Map<String, Integer>> results) {
for (int i = 0; i < threadNum; i++) {
new FileDetector(results, null, files.get(i)).start();
}
}

private static void mergeResulttoFinal(Map<String, Integer> waitforMerge, Map<String, Integer> countResult) {
for (Map.Entry<String, Integer> entry : waitforMerge.entrySet()) {
String word = entry.getKey();
int i = countResult.getOrDefault(word, 0) + entry.getValue();
countResult.put(word, i);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,38 @@
package com.github.hcsp.multithread;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class MultiThreadWordCount5 {
// 使用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 InterruptedException {
List<Map<String, Integer>> results = new ArrayList<>();
Map<String, Integer> countResult = new HashMap<>();
buildDetector(threadNum, files, results);
Thread.sleep(100);

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.

同上。

for (Map<String, Integer> waitforMerge : results) {
mergeResulttoFinal(waitforMerge, countResult);
}
return countResult;
}

private static void buildDetector(int threadNum, List<File> files, List<Map<String, Integer>> results) {
for (int i = 0; i < threadNum; i++) {
new FileDetector(results, null, files.get(i)).start();
}
}

private static void mergeResulttoFinal(Map<String, Integer> waitforMerge, Map<String, Integer> countResult) {
for (Map.Entry<String, Integer> entry : waitforMerge.entrySet()) {
String word = entry.getKey();
int i = countResult.getOrDefault(word, 0) + entry.getValue();
countResult.put(word, i);
}
}
}