Мне нужно написать юнит-тест, который провоцирует состояние гонки, чтобы я мог проверить, возможно, я исправлю проблему позже.Проблема в том, что состояние гонки возникает очень редко, возможно, из-за того, что у моего компьютера только два ядра.
Код выглядит примерно так:
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 теперь выполняет getColonTime (), видит, что datetime по-прежнему равен нулю, и инициализирует его.datetime.colonTime имеет значение null, поэтому второй блок if выполняется, и datetime.colonTime получает значение StringBuilder.Если тогда планировщик останавливает поток между этой строкой и оператором return и возобновляет поток A, происходит следующее: поскольку A был остановлен непосредственно перед вызовом initDateTime, A теперь вызывает initDateTime (), что будет своего рода reset объект datetime, снова устанавливающий значение datetime.colonTime в null.Затем поток A войдет во второй блок if, но планировщик прервет A до datetime.colonTime = sb.toString ();называется.В заключение, dateTime.colonTime по-прежнему равен нулю.Теперь планировщик возобновляет работу B, а метод возвращает значение NULL.
Я попытался спровоцировать состояние гонки, используя несколько потоков, вызывающих getColonTime () для одного (конечного) экземпляра MyDateTime, но в некоторых случаях это не удается.крайне редкие случаи :( Есть какие-нибудь подсказки, как написать "тест" JUnit?