我有一个类(让我们称之为XClass),它有一个方法(让我们称之为xMethod),我正在测试。它还包含:
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:map:{3 = x1,2 = x2,1 = x3,7 = x4,6 = x5,5 = x6, 预期4 = x7,8 = x8}:&lt; 8&gt;但是:&lt; 7&gt;
我通过使用ConcurrentHashMap解决了这个问题,但我仍然对这个问题感到困惑。 在所有8个线程完成之后怎么可能,因为地图表现得很奇怪(size()返回7但toString()打印8个实体)?我会理解是否有7个entites和大小()方法给出了7,但地图中有8个实体。这怎么可能?!
是的,我用两种方式检查了线程的终止: public void run() {
try {
obj = xClass.xMethod();
} catch (Exception e) {
exc = e;
}
finished = true;
}
我只能无限循环,直到所有线程都完成了== true。
所有这些都意味着在继续断言和检查地图之前线程已经完成。那么map.size()有可能返回7而map.toString()返回8个实体吗?
亲切的问候,
霸
答案 0 :(得分:8)
通过同时改变地图,你已经破坏了它的内部不变量,你正在观察未指定和不可预测的行为,这是预期的结果。