単一のスレッドでいくつかの JUnit テストを実行していますが、非決定的な方法で失敗しています。ある人から、最適化 JVM (Oracle Hotspot 64-Bit 17.1-b03) が命令を順不同で実行していると教えてもらいました。Java仕様でそれが許可されているとは信じられませんが、特定の参照が見つかりません.
ウィキペディアは、単一のスレッドがスレッド内 as-if-serial を強制する必要があると述べているため、私が書いたものと異なる実行順序について心配する必要はありません。 http://en.wikipedia.org/wiki/Java_Memory_Model#The_memory_model
コード例:
@Test
public void testPersistence() throws Exception
{
// Setup
final long preTestTimeStamp = System.currentTimeMillis();
// Test
persistenceMethod();
// Validate
final long postTestTimeStamp = System.currentTimeMillis();
final long updateTimeStamp = -- load the timestamp from the database -- ;
assertTrue("Updated time should be after the pretest time", updateTimeStamp >= preTestTimeStamp);
assertTrue("Updated time should be before the posttest time", updateTimeStamp <= postTestTimeStamp);
}
void persistenceMethod()
{
...
final long updateTime = System.currentTimeMillis();
...
-- persist updateTime to the database --
...
}
このテスト コードを実行すると、完全に非決定論的な動作をします。成功する場合もあれば、最初のアサートで失敗する場合もあれば、2 番目のアサートで失敗する場合もあります。値は常に互いに 1 ~ 2 ミリ秒以内であるため、永続化が完全に失敗しているわけではありません。Thread.sleep(2); の追加 各ステートメントの間にテストが失敗する回数は減りますが、失敗を完全に排除するわけではありません。
これは JVM の障害である可能性がありますか、それともデータベース (MsSql) が格納されたデータの何らかの丸め処理を行っている可能性が高いですか?