我正在尝试编写一个测试,以证明在多线程环境中为类的字段分配新的引用不是线程安全的,更具体地说,如果该字段未声明为volatile
或[ C0]。
我使用的场景是AtomicReference
类(如下所示),它应该加载存储在PropertiesLoader
中的一组属性(当前仅使用一个属性),并且还尝试支持重新加载。因此,有许多线程正在读取属性,并且在某个时间点,另一个线程正在重新加载需要对读取线程可见的新值。
该测试旨在按以下方式工作:
Map<String, String>
)现在我知道严格来说,没有测试可以证明一些代码的线程安全性(或缺少代码),但是在这种情况下,我觉得证明该问题相对容易至少根据经验。
我尝试使用PropertyLoader.propertiesMap
实现来存储属性,在这种情况下,即使我仅使用一个读取线程,测试也会按预期挂起。
但是,如果使用HashMap
实现,则无论使用多少读取线程,测试都不会挂起(我也尝试在读取器线程中随机等待,但没有成功。)>
据我所知,ConcurrentHashMap
是线程安全的这一事实不应影响对其分配到的字段的可见性。因此,该字段仍需要ConcurrentHashMap
/ volatile
。但是,上述测试似乎与此矛盾,因为它的行为就像始终安全地发布地图一样,而无需其他同步。
我的理解错误吗?也许AtomicReference
做出了一些其他我不知道的同步承诺?
任何帮助将不胜感激。
P.S。下面的代码应该可以作为Junit测试执行。我已经在装有AMD Ryzen 5,Windows 10,JDK 1.8.0_201的计算机上运行了它,并在另一台装有i7英特尔的Fedora 30,JDK 1.8.xx(不记得JDK的确切版本)的计算机上运行了相同的结果。
ConcurrentHashMap
我正在尝试编写一个测试,以证明在多线程环境中为类的字段分配新的引用不是线程安全的,如果存在该问题,更具体地说是具有可见性问题...