1
對於同一組文件,每次運行的計數都會發生變化。 以下代碼仍然不符合數據。如何使線程安全?簡單的字數統計代碼。使用ConcurrentHashMap的數據不一致
package ConcurrentHashMapDemo;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
class FileReaderTask implements Runnable {
private String filePath;
private String fileName;
private ConcurrentMap<String, Integer> wordCountMap;
public FileReaderTask(String filePath, String fileName,
ConcurrentMap<String, Integer> wordCountMap) {
this.filePath = filePath;
this.fileName = fileName;
this.wordCountMap = wordCountMap;
}
public void run() {
File jobFile = new File(filePath + fileName);
try {
BufferedReader bReader = new BufferedReader(new FileReader(jobFile));
String line = "";
while ((line = bReader.readLine()) != null) {
String[] strArray = line.split(" ");
for (String str : strArray) {
if (wordCountMap.containsKey(str)) {
wordCountMap.replace (str.trim(),
wordCountMap.get(str.trim()) + 1);
} else {
wordCountMap.putIfAbsent(str.trim(), 1);
}
}
}
//Thread.sleep(10000);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public class Main {
public static void main(String[] args) {
ConcurrentMap<String, Integer> wordCountMap = new ConcurrentHashMap<String, Integer>();
File fileDir = new File("c://job_files");
Thread[] threads = new Thread[fileDir.listFiles().length];
for(int i=0;i<threads.length;i++){
FileReaderTask frt = new FileReaderTask("c:/job_files/", fileDir.listFiles()[i].getName(), wordCountMap);
threads[i]= new Thread(frt);
threads[i].start();
}
//
for(int i=0;i<threads.length;i++){
try {
threads[i].join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
for(Map.Entry<String, Integer> entry: wordCountMap.entrySet()){
String key = entry.getKey();
System.out.println(key +" - - "+wordCountMap.get(key));
}
System.out.println("Main");
}
}
這works.Thanks多 – KDP
能否請您讓我知道while循環的目的,在這裏? – KDP
當競爭條件發生時,映射中的值由另一個線程在「putIfAbsent」和「replace」調用之間更改。這會導致替換返回'false'。循環將再次嘗試增量,並以新更新的值開始。 –