volatile数组和引用的局部性

时间:2013-10-21 16:52:19

标签: java multithreading concurrency volatile cpu-cache

参考地点。http://en.wikipedia.org/wiki/Locality_of_reference。 因此,迭代一个小的int数组会比迭代一个linkedList更快。 因为数组是连续的,所有数组都可以放在cpu缓存中 会减少缓存未命中。

但我想要一个简单的int数组和一个volatile数组之间的比较。在易失性数组上迭代的AFAIK将导致每次都发生易失性读取,这可能在某些系统中产生 在每次阅读时更新缓存。

int[] arr; // assume here i have declared and initialized it.
int sum = 0;
for(int i=0;i<arr.length;i++){
    sum = sum + arr[i];
}

易变的对应部分

volatile int[] arr; // assume here i have declared and initialized it.
int sum = 0;
for(int i=0;i<arr.length;i++){
    sum = sum + arr[i]; // volatile read everytime
}

它们是相同的,或者编译器会将所有易失性读取转换为单个易失性读取(编译器优化)

2 个答案:

答案 0 :(得分:3)

如果您需要对阵列进行易失性访问,则可以使用AtomicIntegerArray。这包装了一个int数组,但给出了线程安全的语义。

AtomicIntegerArray array = new AtomicIntegerArray(100);
array.addAndGet(1);
array.lazySet(10, 123);
int n = array.get(5); // volatile get
array.set(9, 333); // volatile set.

答案 1 :(得分:0)

对Scientist的代码略有改进:你实际上并不需要一个额外的易失性布尔标志,你可以通过以下方式获得:

volatile int[] array = ...;

void write(int index, int value){
    array[index]=value;
    array = array; // explicit volatile write
}

int read(int index){
    return array[index]; // implicit volatile read
}

主要的变化是你不需要为读取额外读取volatile变量,因为访问数组的第i个元素涉及读取对数组的volatile引用(JIT /编译器实际上是否为不同的东西,但它必须给你相同的保证)。所以这很好,因为它正是你所编写的代码。 遗憾的是,对于数组的写入不起作用,所以你必须做这个非常难看的自我分配。

那就是说AtomicIntegerArray类和它一样有效(至少你希望如此)并使整个事情变得明确。