Java,会不稳定也能保证可见性?
public class Stuff { private final Timer timer = new Timer(true); public static final int DEFAULT_TIMEOUT = 1500; private volatile int timeout = DEFAULT_TIMEOUT; public void doStuff(OtherStuff) { ... timer.schedule(timeout,...); } public void setTimeout(int timeout) { this.timeout = timeout; } public int getTimeout() { return timeout; } } 除了可以从另一个类更改的超时变量外,只从1个线程访问此类的实例.在我的例子中是一个JMX bean,这意味着可以在运行时从管理界面改变超时. doStuff()可以运行100次/秒,而setTimeout()可以每周运行一次 – 因此执行setTimeout()的人和执行doWork()的人之间的顺序并不重要. 对于这种情况,超时是否足够?内存模型是否可以保证将一个线程设置为doStuff()方法可见? 另一种似乎安全的替代方案就是: public class Stuff { private final Timer timer = new Timer(true); public static final int DEFAULT_TIMEOUT = 1500; private int timeout = DEFAULT_TIMEOUT; public void doStuff(OtherStuff) { ... timer.schedule(getTimeout(),...); } public void synchronized setTimeout(int timeout) { this.timeout = timeout; } public int synchronized getTimeout() { return timeout; } } 哪两种方法更受青睐? 解决方法
从可见性的角度来看,两种方法都是等价的.在对同一个volatile变量进行写操作之后发生的对volatile的任何读取都可以保证看到写入.
因此,如果一个线程写入timeout = newValue;,则随后调用timer.schedule(timeout)的任何其他线程都将保证看到newValue. 此保证在JLS 17.4.5中指定:
我会简单地使用volatile作为它提供的保证就足够了,它清楚地显示了你的意图. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |