使用ThreadPoolExecutor.execute()保证内存可见性

时间:2011-11-16 03:14:20

标签: java multithreading jvm thread-safety

如果使用ThreadPoolExecutor执行Runnable,并且此Runnable修改了某个共享状态,是否可以保证在提交runnable的原始线程中对共享状态的这些更改是否可见游泳池?假设只有一个作家共享州和一个读者。我知道当您使用返回ExecutorService的{​​{1}}时,执行Future将保证可见性。

Future.get()

2 个答案:

答案 0 :(得分:5)

这取决于,没有隐含的保证状态的更改将立即反映在原始线程中,主要是因为原始线程可能具有x的值的缓存副本,当时不会更新另一个线程更改了主内存中x的值。

您可以使用volatile关键字添加明确的保证来解决此问题,例如:

class State {
    private volatile int x;
    public State(int y) { x = y; }
    public void setX(int y) { x = y; }
    public int getX() { return x; }
}

这告诉编译器它不能缓存x的值,并且每次程序读取x时它必须检查主内存中的值。这将导致原始线程在任何其他线程修改它时立即看到x的新值。

此处有更多详情:

http://www.javamex.com/tutorials/synchronization_volatile.shtml

答案 1 :(得分:1)

几乎任何理智的方法来检测线程已完成其工作(除volatile除了只同步该一个变量之外)还将保证内存的同步视图。你的例子无法确定线程是否已经完成,所以它显然不起作用。 C#不提供任何特定的及时性保证,因此您不能将sleep用作同步形式。