경쟁 상태를 유발하는 단위 테스트를 작성해야하므로 나중에이 문제를 해결할 수 있는지 테스트 할 수 있습니다. 문제는 경쟁 조건이 매우 드물게 발생한다는 것입니다. 내 컴퓨터에는 코어가 두 개 밖에 없기 때문일 수 있습니다.Java에서 경쟁 조건 실행
코드는 같은 것입니다 다음
class MyDateTime {
String getColonTime() {
// datetime is some kind of lazy caching variable declared somewhere(does not matter)
if (datetime == null) {
initDateTime(); //Uses lazy to initlialize variable, takes some time
}
// Colon time stores hh:mm as string
if (datetime.colonTime == null) {
StringBuilder sb = new StringBuilder();
//Now do some steps to build the hh:mm string
//...
//set colon time
datetime.colonTime = sb.toString();
}
return datetime.colonTime;
}
}
설명 : 우리가 게으른 초기화 원하는대로 내가 언급 한 바와 같이, ( initDateTime가 dateTime에 대한 새로운 인스턴스를 할당, 그 때문에, datetime.colonTime 나중에 널 전에). 이제 스레드 A가 메소드에 진입 한 후 스케줄러가 initDateTime()을 실행할 수 있기 직전에 스레드를 중지합니다. 스레드 B는 이제 runst getColonTime(), datetime이 여전히 null이며 초기화되어 있음을 확인합니다. datetime.colonTime은 null이므로 블록이 실행되면 두 번째이고 datetime.colonTime은 StringBuilder의 값을 가져옵니다. 스케쥴러가이 행과 return 문 사이의 스레드를 중지하고 스레드 A를 재개하면 다음과 같이됩니다. initDateTime이 호출되기 바로 전에 A가 중지되었으므로 A가 을 초기화하는 initDateTime()을 호출합니다. datetime.colonTime을 null로 다시 설정하십시오. 스레드 A는 두 번째 if 블록을 입력하지만 스케줄러는 datetime.colonTime = sb.toString()보다 먼저 A를 인터럽트합니다. 호출됩니다. 결론적으로 dateTime.colonTime은 여전히 null입니다. 이제 스케줄러가 B를 다시 시작하고 메서드는 null을 반환합니다.
getColonTime()을 MyDateTime의 단일 (최종) 인스턴스에 호출하는 스레드가 많아서 경쟁 조건을 유발하려고 시도했지만 일부 드문 경우에만 실패합니다. ( JUnit을 작성하는 방법에 대한 힌트 "테스트"?
우선 경쟁 조건을 유발하기 위해 디버거를 사용해 볼 수 있습니다. 나는. 스레드를 시작하고 중단 점 (예 : 사이)에서 잡아서 다른 스레드를 시작하십시오. RC가 어떻게 발생했는지 생각한 후에 (지금은 아무 것도없는 것 같습니다) 성공적인 단위 테스트를 작성할 수 있습니다. – pupssman
'return datetime에 도달하는 방법을 보지 못했습니다.colonTime;'을 반환하고 null을 반환합니다. hh : mm 문자열을 작성하는 방법에 문제가 없다고 확신합니까? 어쩌면 그 코드를 질문에 추가하여 그 코드를 볼 수 있습니다. – Windle
나는 그것이 일어날 수있는 몇 가지 추가 설명을 추가했다. 매우 명확하지는 않다는 것을 인정해야합니다. – user3001