对象构造完成后,怎样才算「安全发布」给其它线程?这篇把几种常见发布方式放进同样的场景:读线程在热循环里等对象出现,看哪些能看到、看到的对象是否完整(final 字段与内存序见前两篇)。
plain:3 秒后读线程仍然没有看到发布的对象(循环没有结束) volatile:循环在 207 ms 后结束,读到对象 a = 1,b = 2,items = [x, y] atomic:循环在 209 ms 后结束,读到对象 a = 1,b = 2,items = [x, y] synchronized:循环在 210 ms 后结束,读到对象 a = 1,b = 2,items = [x, y] chm:循环在 204 ms 后结束,读到对象 a = 1,b = 2,items = [x, y]
start:Thread.start() 之前写入的普通字段,新线程里读到 plain.a = 1,items = [x, y] join:被 join 的线程里写入的普通字段,join 返回后读到 plain.a = 7,items = [x, y] holder:类初始化器里构造的 static final 对象,另一个线程第一次访问 Holder.INSTANCE 读到 a = 1,items = [x, y]