我有一個偶爾出現奇怪行爲的ConcurrentHashMap。Java ConcurrentHashMap損壞值
當我的應用第一次啓動時,我從文件系統讀取一個目錄,並將每個文件的內容加載到ConcurrentHashMap中,並使用文件名作爲關鍵字。某些文件可能爲空,在這種情況下,我將該值設置爲「空」。
所有文件加載完成後,工作線程池將等待外部請求。當請求進來時,我調用getData()函數,在這裏我檢查ConcurrentHashMap是否包含密鑰。如果密鑰存在,則獲取該值並檢查該值是否爲「空」。如果value.contains(「空」),我返回「找不到文件」。否則,返回文件的內容。當密鑰不存在時,我嘗試從文件系統加載文件。
private String getData(String name) {
String reply = null;
if (map.containsKey(name)) {
reply = map.get(name);
} else {
reply = getDataFromFileSystem(name);
}
if (reply != null && !reply.contains("empty")) {
return reply;
}
return "file not found";
}
有時,ConcurrentHashMap就返回一個非空文件(即value.contains("empty") == false
)的內容,但是該行:
if (reply != null && !reply.contains("empty"))
返回FALSE。我將IF聲明分爲兩部分:if (reply != null)
和if (!reply.contains("empty"))
。 IF語句的第一部分返回TRUE。第二部分返回FALSE。所以我決定打印出變量「reply」,以確定字符串的內容是否確實包含「empty」。這不是這種情況,即內容不包含字符串「空」。此外,我增加了行
int indexOf = reply.indexOf("empty");
自變量回復未包含字符串「空」當我打印出來,我期待indexOf
返回-1。但函數返回的值大約爲字符串的長度,即if reply.length == 15100
,然後reply.indexOf("empty")
返回15099.
我每週都會遇到此問題,每週大約2-3次。此過程每天重新啓動,因此定期重新生成ConcurrentHashMap。
有沒有人在使用Java的ConcurrentHashMap時看到過這樣的行爲?
編輯
private String getDataFromFileSystem(String name) {
String contents = "empty";
try {
File folder = new File(dir);
File[] fileList = folder.listFiles();
for (int i = 0; i < fileList.length; i++) {
if (fileList[i].isFile() && fileList[i].getName().contains(name)) {
String fileName = fileList[i].getAbsolutePath();
FileReader fr = null;
BufferedReader br = null;
try {
fr = new FileReader(fileName);
br = new BufferedReader(fr);
String sCurrentLine;
while ((sCurrentLine = br.readLine()) != null) {
contents += sCurrentLine.trim();
}
if (contents.equals("")) {
contents = "empty";
}
return contents;
} catch (Exception e) {
e.printStackTrace();
if (contents.equals("")) {
contents = "empty";
}
return contents;
} finally {
if (fr != null) {
try {
fr.close();
} catch (Exception e) {
e.printStackTrace();
}
}
if (br != null) {
try {
br.close();
} catch (Exception e) {
e.printStackTrace();
}
}
if (map.containsKey(name)) {
map.remove(name);
}
map.put(name, contents);
}
}
}
} catch (Exception e) {
e.printStackTrace();
if (contents.equals("")) {
contents = "empty";
}
return contents;
}
return contents;
}
我簡直不相信'foo.indexOf(「empty」)'會永遠*返回'foo.length() - 1'爲非空字符串。這意味着'String.indexOf'已經很糟糕了。我不相信'ConcurrentHashMap'或'String'被破壞 - 我強烈懷疑你的代碼是在某處破壞的。 – 2012-07-09 18:52:24
你可以顯示'getDataFromFileSystem(name);'的代碼嗎? – assylias 2012-07-09 18:56:43
是_actual_ getData()方法,還是您重新將它發佈在這裏? – jtahlborn 2012-07-09 19:13:15