경우에 따라 이상한 동작을 나타내는 ConcurrentHashMap가 있습니다.Java ConcurrentHashMap 타락한 값
내 응용 프로그램이 처음 시작되면 파일 시스템에서 디렉토리를 읽고 파일 이름을 키로 사용하여 각 파일의 내용을 ConcurrentHashMap에로드합니다. 일부 파일은 비어있을 수 있습니다.이 경우 값을 "비어 있음"으로 설정합니다.
일단 모든 파일이로드되면 작업자 스레드 풀은 외부 요청을 기다립니다. 요청이 들어 오면 ConcurrentHashMap에 키가 들어 있는지 확인하는 getData() 함수를 호출합니다. 키가 있으면 값을 가져 와서 값이 "비어 있는지"확인하십시오. value.contains ("empty") 인 경우, "file not found"를 반환합니다. 그렇지 않으면 파일 내용이 리턴됩니다. 키가 존재하지 않으면 파일 시스템에서 파일을로드하려고합니다.
if (reply != null && !reply.contains("empty"))
반환 FALSE :
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 문을 두 부분으로 나누었습니다 : if (reply != null)
과 if (!reply.contains("empty"))
. IF 문의 첫 번째 부분은 TRUE를 반환합니다. 두 번째 부분은 FALSE를 반환합니다. 그래서 문자열의 내용에 실제로 "empty"가 포함되어 있는지 확인하기 위해 변수 "reply"를 출력하기로 결정했습니다. 이는 사실이 아니 었습니다. 즉, 내용에 문자열 "empty"가 포함되지 않았습니다. 나는 그것을 밖으로 인쇄 할 때 또한, 내가 돌아 indexOf
를 기다리고 있었다 "빈"문자열을 포함하지 않은 변수 응답 이후 라인
int indexOf = reply.indexOf("empty");
을 추가 -1. 그러나이 함수는 문자열 길이의 대략적인 값, 즉 if reply.length == 15100
을 반환하고 reply.indexOf("empty")
은 15099를 반환했습니다.
주간 단위로 약 2-3 회이 문제가 발생합니다. 이 프로세스는 매일 다시 시작되므로 ConcurrentHashMap은 정기적으로 다시 생성됩니다.
Java ConcurrentHashMap을 사용할 때 이러한 동작을 본 사람이 있습니까? 당신이 순서대로 여러 스레드에서 메서드를 호출하는 경우 당신을 보호하지 않습니다 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' 중 하나가 망가 졌다고 생각하지 않습니다 - 코드가 어딘가에서 깨졌습니다. –
'getDataFromFileSystem (name);'의 코드를 보여줄 수 있습니까? – assylias
은 _actual_ getData() 메소드이거나 여기에 게시하기 위해 재 작업 했습니까? – jtahlborn