업데이트를 잘못된 값을 반환 : 그것은이 지침의 단지 몇에 사용 된 몇 가지 코드에 깊이 묻혀 정적이었다. 제안 해 주셔서 감사합니다.자바의 HashMap 때때로 일부 스레드
우리는 스레드에서 하나의 HashMap를 (예 즉 여러 가지 이유로 나쁜) 사용하고 있지 않습니다. 각 thread에는, 독자적인 HashMap가 있습니다.
우리는 스레드에서 확장하는 클래스를 가지고있다. Thread.run()에서 우리는 HashMap을 만들고, 그 안에 키/값 쌍을 설정하고, 그 HashMap을 메서드에 전달합니다. 이 메서드는 HashMap에서 값을 가져 와서 문자열에 삽입하고 문자열을 반환합니다.
때때로 반환 된 문자열이 다른 값이 (여전히 Thread.run에서을()). 이것은 3 개 이상의 물리적 코어가있는 하드웨어에서만 발생합니다. 그리고 그것은 단지 두 번 일어났습니다 (우리가 로깅을 추가하기 전에 정확히 무슨 일이 일어나는지 정확히 알 수 있습니다).
왜 이런 일이 발생하는지 알고 싶습니다.
업데이트 : 전체 코드는 여기에 있습니다. ProcessTxt는 HashMap에서 값을 가져 와서 문자열에 넣는 것입니다.
import java.io.*;
import java.util.HashMap;
import junit.framework.TestCase;
import net.windward.datasource.dom4j.Dom4jDataSource;
import net.windward.xmlreport.ProcessReport;
import net.windward.xmlreport.ProcessTxt;
/**
* Test calling from multiple threads
*/
public class TestThreads extends TestCase {
private static String path = ".";
// JUnit stuff
public TestThreads(String name) {
super(name);
}
// Get logging going - called before any tests run
protected void setUp() throws Exception {
ProcessReport.init();
}
// this is not necessary - called after any tests are run
protected void tearDown() {
}
private static final int NUM_THREADS = 100;
private boolean hadWithVarError = false;
/**
* Test that each thread has unique variables.
*/
public void testRunReportsWithVariables() throws Exception {
// run 10 threads
ReportThreadWithVariables[] th = new ReportThreadWithVariables[NUM_THREADS];
for (int ind = 0; ind < NUM_THREADS; ind++) {
th[ind] = new ReportThreadWithVariables(this, ind);
th[ind].setName("Run " + ind);
}
for (int ind = 0; ind < NUM_THREADS; ind++)
th[ind].start();
boolean allDone = false;
while (!allDone) {
Thread.sleep(100);
allDone = true;
for (int ind = 0; ind < NUM_THREADS; ind++)
if (th[ind].isAlive())
allDone = false;
}
assertTrue(!hadWithVarError);
}
public static class ReportThreadWithVariables extends Thread {
private TestThreads obj;
private int num;
public ReportThreadWithVariables(TestThreads tt, int num) {
obj = tt;
this.num = num;
}
public void run() {
try{
System.out.println("starting " + num);
ByteArrayOutputStream out = new ByteArrayOutputStream();
ProcessTxt pt = new ProcessTxt(new FileInputStream(new File(path, "Thread_Test.docx")), out);
pt.processSetup();
// don't use order1.xml, but need a datasource.
Dom4jDataSource datasource = new Dom4jDataSource(new FileInputStream(new File(path, "order1.xml")));
HashMap map = new HashMap();
map.put("num", new Integer(num));
datasource.setMap(map);
pt.processData(datasource, "");
pt.processComplete();
String result = out.toString().trim();
System.out.println("complete " + num + ", result = " + result);
String expected = "Number: " + num;
if (!result.equals(expected))
obj.hadWithVarError = true;
assertEquals(expected, result);
} catch (Throwable e) {
obj.hadWithVarError = true;
e.printStackTrace();
}
}
}
}
(형식 코드 편집)
키 란 무엇입니까? 문제를 시연하는 짧지 만 완전한 프로그램은 실제로 도움이 될 것입니다. –
어떤 유형의 값이 적합 할 수도 있습니다. 값이 다른 곳에서 참조되고 나중에 수정되는 객체를 포함 할 수 있습니까? – VeeArr
몇 가지 샘플 코드를 추가하십시오. –