【发布时间】:2012-02-08 07:31:30
【问题描述】:
关于 JMM 的问题以及关于在同步块中写入但未同步读取的 volatile 字段的语义。
在以下代码的初始版本中,我没有同步访问,因为它对于早期的要求是不必要的(并且滥用自赋值 this.cache = this.cache 确保了易失性写入语义)。某些要求已更改,需要同步以确保不会发送重复的更新。我的问题是同步块是否排除需要 volatile 字段的自分配?
// Cache of byte[] data by row and column.
private volatile byte[][][] cache;
public byte[] getData(int row, int col)
{
return cache[row][col];
}
public void updateData(int row, int col, byte[] data)
{
synchronized(cache)
{
if (!Arrays.equals(data,cache[row][col]))
{
cache[row][col] = data;
// Volatile write.
// The below line is intentional to ensure a volatile write is
// made to the array, since access via getData is unsynchronized.
this.cache = this.cache;
// Notification code removed
// (mentioning it since it is the reason for synchronizing).
}
}
}
如果没有同步,我认为自赋值 volatile 写入在技术上是必要的(尽管 IDE 将其标记为无效)。对于同步块,我认为它仍然是必要的(因为读取是不同步的),但我只是想确认一下,因为如果实际上不需要它,它在代码中看起来很荒谬。我不确定在同步块结束和易失性读取之间是否有任何我不知道的保证。
【问题讨论】:
标签: java multithreading thread-safety