私は以前、メモリー・モデル・リストでテスト目的で JVM を動作させる最悪のケースを提案しましたが、そのアイデアは人気がないようでした。
したがって、既存のテクノロジーを使用して「最悪の場合のJVM動作」を実現する方法、つまり、問題のシナリオをテストして毎回失敗させるにはどうすればよいですか。可能な限り最も弱いメモリ モデルでセットアップを見つけようとすることもできますが、それが完璧である可能性は低いです。
私がよく考えてきたのは、分散型 JVM を使用することです。これは、Terracotta がカバーの下で動作すると私が信じている方法に似ているため、アプリケーションは複数の JVM (リモートまたはローカル) で実行されます (同じアプリケーションのスレッドは異なるインスタンスで実行されます)。このセットアップでは、JVM スレッド間通信がメモリ バリアで行われます。たとえば、バグのあるコードで欠落している同期キーワード (Java メモリ モデルに準拠している) があり、アプリケーションが構成されています。つまり、このクラス スレッドはここで実行されます。構成だけでテストにコード変更は必要ありません。適切に順序付けされた Java アプリケーションはそのまま実行する必要がありますが、このセットアップは、順序付けが不適切なアプリケーションには非常に不寛容です (通常は問題です...現在は資産、つまりメモリ モデルは非常に弱いが合法的な行動)。setValueは、コードが変更され、同期されたり、揮発性などが使用されたりしない限り、他のスレッドに影響を与えません。その後、コードは意図したとおりに機能します。
上記の例 (正しく構成されている) のテストは、テストに非常に役立つ可能性のある正しい「注文前に発生する」ことがないと、毎回失敗します。完全にカバーするための計画の欠陥は、アプリケーション スレッドごとに 1 つのノード (同じマシンまたはクラスター内の複数のマシン) または複数のテスト実行が必要になる可能性があります。数千のスレッドがある場合、それは法外なものになる可能性がありますが、うまくいけば、それらはプールされ、E2E テスト シナリオ用に縮小されるか、クラウドで実行されます。この種のセットアップは、問題を実証するのに役立つ場合があります。
JVM 間のスレッド間通信