時々奇妙な動作を示す ConcurrentHashMap があります。
アプリの初回起動時に、ファイル システムからディレクトリを読み取り、ファイル名をキーとして使用して各ファイルの内容を ConcurrentHashMap に読み込みます。一部のファイルは空である可能性があり、その場合は値を「空」に設定します。
すべてのファイルがロードされると、ワーカー スレッドのプールが外部要求を待ちます。リクエストが来ると、getData() 関数を呼び出して、ConcurrentHashMap にキーが含まれているかどうかを確認します。キーが存在する場合は、値を取得し、値が「空」かどうかを確認します。value.contains("empty") の場合、"ファイルが見つかりません" を返します。それ以外の場合は、ファイルの内容が返されます。キーが存在しない場合は、ファイル システムからファイルをロードしようとします。
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 ステートメントを と の 2 つの部分に分けましif (reply != null)
たif (!reply.contains("empty"))
。IF ステートメントの最初の部分は TRUE を返します。2 番目の部分は FALSE を返します。そこで、文字列の内容に実際に「空」が含まれているかどうかを判断するために、変数「reply」を出力することにしました。これは事実ではありませんでした。つまり、内容に文字列「empty」が含まれていませんでした。さらに、行を追加しました
int indexOf = reply.indexOf("empty");
印刷したときに変数の応答に文字列「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;
}