java – 相对于其他字段的易失语义
假设我有以下代码
private volatile Service service; public void setService(Service service) { this.service = service; } public void doWork() { service.doWork(); } 被修改的字段标记为volatile,其值不依赖于以前的状态.因此,这是正确的多线程代码(不要在一分钟内麻烦服务实现). 据我所知,读取易失性变量就像进入锁一样,从内存可见性的角度来看.这是因为正常变量的读取不能用读取volatile变量来重新排序. 这是否意味着以下代码是正确的? private volatile boolean serviceReady = false; private Service service; public void setService(Service service) { this.service = service; this.serviceReady = true; } public void doWork() { if ( serviceReady ) { service.doWork(); } } 解决方法
是的,这个代码是“正确的”,就像Java 1.5一样.
原子性不是一个问题,有或没有volatile(对对象引用的写入是原子的),所以你可以以任何方式将关系列表从这个关系列表中传出 – 唯一的问题是更改的可视性和排序的“正确性”. 对volatile变量的任何写入都将设置一个“发生之前”关系(新的Java内存模型的关键概念,如JSR-133中所述),同时可以读取相同的变量.这意味着阅读线程必须能够看到写入线程可见的所有内容:也就是说,在写入时它必须至少看到所有具有’current’值的变量. 我们可以通过查看section 17.4.5 of the Java Language Specification详细解释这一点,具体说明如下要点: >“如果x和y是同一个线程的动作,而x在程序顺序中出现在y之前,那么hb(x,y)”(即,同一个线程上的动作不能以与程序顺序不一致的方式重新排序) 所以在你的例子中: >写入’service'(a)发生在写入’serviceReady'(b)之前,由于规则1 这意味着您确保’service’设置正确,在这种情况下,一旦serviceReady为true. 您可以使用几乎完全相同的示例看到一些好的写作,一个在IBM DeveloperWorks – 参见“新的易失性保证”:
和一个在the JSR-133 FAQ,由JSR的作者写道:
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |