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

Я пытался спровоцировать состояние гонки, имея несколько потоков, вызывающих getColonTime () для единственного (последнего) экземпляра MyDateTime, но это терпит неудачу только в очень редких случаях: ( Любые подсказки, как написать "тест" JUnit?

7
задан user3001 16 September 2011 в 20:24
поделиться