alternatives for volatile array

不问归期 提交于 2020-01-13 05:16:07

问题


From other questions, I learned that the elements of a volatile array are not volatile. Only the reference itself is volatile.

volatile[] int data;

Thread A: data[4] = 457;
Thread B: System.out.println(data[4]);

Here, Thread B might never see the updated value.

Which options/alternatives do I have to achieve the same thing? I would like to avoid having to synchronize the array, since it is hardly ever altered. However, it is being read a lot by some threads. Synchronizing it will very likely lower the throughput, which is very important in this example.

Is my only option a copy-on-write data-structure here? That is, copying the array into a new array and update the array reference afterwards.

Are there any other options? I read somewhere that encapsulating the array into a class (with only one member, the array) achieves the same thing, but I doubt that is true. I cannot see how that might help.

Please note that my target JVM is 1.4. This means I cannot use the java.util.concurrent package.

-------------- edit edit edit --------------

In Java volatile array? I read that re-assigning the array reference achieves the volatility semantics. This should give the correct results:

volatile[] int data;

Thread A: data[4] = 457;
Thread A: data = data;
Thread B: System.out.println(data[4]);

Is this valid on older JVMs?


回答1:


An array is marked volatile, that is only the reference is marked as volatile. The elements of array itself do not inherit the memory visibility semantics of the volatile keyword at all.

What I can suggest build a AtomicIntergerArray class in your own. Where you can keep a final int[] data refernece and synchronize it properly.

Also take a look on AtomicIntergerArray implementation code.

Or else you can use Backport api's AtomicIntegerArray.

This project is to provide a concurrency library that works with uncompromised performance on all Java platforms currently in use, allowing development of fully portable concurrent applications. More precisely, the traget scope is Java 1.3 and above, and some limited support if offered for Java 1.2.




回答2:


Just use wrapper:

class VolatileInt{
    volatile int value;
}

VolatileInt[] create(int size){
    VolatileInt[] array = new VolatileInt[size];
    for(int k=0;k<size;k++)
        array[k]=new VolatileInt();
    return array; 
}

VolatileInt[] array = create(10);



回答3:


Using arr=arr manages Java to rewrite the storage address of the array (arrays are also objects in Java). The array fields arr[i] do not gain the volatile property.

In some cases, arr=arr might work for unknown reasons, but it does not bring you to the safe side.

If you want to stay safe, use the Atomic*Array stuff. Yes, the extra atomicity is costly, but I guess if you consider access times and storage footprint it is better than linked structures.

If you want to avoid global locks, you may consider to split the array into subsets. This makes locks affect only a subset and you still keep the volatility for all values.

I share your problem, by best bet are Atomic*Arrays.



来源:https://stackoverflow.com/questions/15739942/alternatives-for-volatile-array

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!