私がテストしているメソッド(xMethodと呼びましょう)を持つクラス(XClassと呼びましょう)があります。また、以下も含まれます。
private static Map<String, String> map = new HashMap<String, String>();
単体テストのセットアップ方法には次のものがあります。
ReflectionTestUtils.setField(xClass, "map", map, null);
テスト メソッドでは、いくつか (私の場合は 8 つ) のスレッドを作成します。run メソッドは xClass.xMethod を呼び出します。このメソッドは、静的マップ変数を変更します。メソッド xMethod は、map.containsKey()、map.get()、および map.put() を 8 回呼び出すことになっています。削除はしません。また、このメソッドは新しいスレッドを作成しないため、スレッドが xMethod で終了したら、マップを変更しないでください。すべてのスレッドが終了するのを待ちます (通常または例外によって)。地図を確認するより
int mapSize = map.size();
assertEquals("map:" + map, 8, mapSize);
ここで失敗し、次のメッセージが表示されます。
java.lang.AssertionError: マップ:{3=x1, 2=x2, 1=x3, 7=x4, 6=x5, 5=x6, 4=x7, 8=x8} 予想:<8> だった:< 7>
ConcurrentHashMap を使用して問題を解決しましたが、まだ問題に戸惑っています。8 つのスレッドがすべて終了した後、マップが奇妙な動作をする (size() は 7 を返すが、toString() は 8 つのエンティティを出力する) 可能性はありますか? 7 つのエンティティがあり、size() メソッドが 7 を返した場合は理解できましたが、マップには 8 つのエンティティがあります。これはどのように可能ですか?
ところで、私はいくつかの方法でスレッドの終了をチェックしまし
た: 1. Thread.State.TERMINATED をチェックします。
2.メソッドが戻る前に簡単なメッセージを出力し、スレッドが完了した後に簡単なメッセージを出力しました(そして、例外がスローされていないことを確認しました。8つのメッセージは常に9番目の前に書き込まれます(スレッドが「終了」した後のテストで)。
3. run メソッドに次のロジックを含む単純なスレッドを実行しました。
public void run() {
try {
obj = xClass.xMethod();
} catch (Exception e) {
exc = e;
}
finished = true;
}
すべてのスレッドが終了 == true になるまで、無期限にループするだけです。
これらはすべて、マップのアサートとチェックを続行する前に、スレッドが終了していることを意味します。それでは、どうすれば map.size() が 7 を返し、map.toString() が 8 つのエンティティを返すことができるのでしょうか?!
敬具、
デスポット