如何在Java中声明数组元素?
有没有一种方法可以在Java中声明数组元素如何在Java中声明数组元素?,java,arrays,concurrency,volatile,Java,Arrays,Concurrency,Volatile,有没有一种方法可以在Java中声明数组元素volatile?即 volatile int[] a = new int[10]; 声明数组引用volatile,但数组元素(例如a[1])仍然不是volatile。所以我在找类似的东西 volatile int[] a = new volatile int[10]; 但不是这样的。有可能吗?使用AtomicIntegerArray或AtomicLongArray或AtomicReferenceArray AtomicIntegerArray类实现
volatile
?即
volatile int[] a = new int[10];
声明数组引用volatile
,但数组元素(例如a[1]
)仍然不是volatile。所以我在找类似的东西
volatile int[] a = new volatile int[10];
但不是这样的。有可能吗?使用
AtomicIntegerArray
或AtomicLongArray
或AtomicReferenceArray
AtomicIntegerArray
类实现了一个int数组,通过该类的get()
和set()
方法,可以使用volatile语义访问该数组的各个字段。从一个线程调用arr.set(x,y)
将保证调用arr.get(x)
的另一个线程将读取值y(直到另一个值被读取到位置x)
见:
- 包摘要
Atomic
xxxArray
类的源代码中所看到的,这些类也使用VarHandle
,因为JDK 9:
//[...]
private static final VarHandle AA
= MethodHandles.arrayElementVarHandle(int[].class);
private final int[] array;
//[...]
/**
* Returns the current value of the element at index {@code i},
* with memory effects as specified by {@link VarHandle#getVolatile}.
*
* @param i the index
* @return the current value
*/
public final int get(int i) {
return (int)AA.getVolatile(array, i);
}
/**
* Sets the element at index {@code i} to {@code newValue},
* with memory effects as specified by {@link VarHandle#setVolatile}.
*
* @param i the index
* @param newValue the new value
*/
public final void set(int i, int newValue) {
AA.setVolatile(array, i, newValue);
}
//[...]
首先创建一个VarHandle
,如下所示:
MethodHandles.arrayElementVarHandle(yourArrayClass)
例如,您可以在此处输入byte[].class
,自己实现缺少的AtomicByteArray
然后,您可以使用set
xxx(数组,索引,值)
和get
xxx(数组,索引)
方法访问它,其中array
的类型为yourrarrayclass
,index
的类型为int
,value
的类型为数组中的元素(yourArrayClass.getComponentType()
)
请注意,例如,如果yourArrayClass==byte[].class
但输入42
作为值
,则会出现错误,因为42
是int
而不是byte
,并且访问方法的参数是vararg对象…
参数:
java.lang.invoke.WrongMethodTypeException: cannot convert MethodHandle(VarHandle,byte[],int,byte)void to (VarHandle,byte[],int,int)void
(第二个签名是您使用的,第一个签名是您应该使用的。)
请注意,JDK 8及以下版本中用于实现原子类,如: (现在应该修复了)这个怎么样:
static class Cell<T> {
volatile T elem;
}
private Cell<T>[] alloc(int size){
Cell<T>[] cells = (Cell<T>[]) (new Cell[size]);
return cells;
}
volatile Cell<T>[] arr;
Cell<T>[] newarr = alloc(16);
for (int i = 0; i < newarr.length; i++) {
newarr[i] = new Cell<>();
}
arr = newarr;
静态类单元格{
挥发性T元素;
}
专用单元格[]alloc(整数大小){
单元格[]单元格=(单元格[])(新单元格[大小]);
返回单元;
}
挥发性细胞[]arr;
单元格[]newarr=alloc(16);
for(int i=0;i
单元格也会使内容变得不稳定。另外,我只有在预先分配单元格后才将新数组分配给不稳定的数组……单元格额外内存有一个折衷,但它是可管理的实际上你可以,但需要额外的努力。从技术上讲,这仍然不会使元素变得不稳定,但数组操作是不稳定的。Since
int
对于这种情况,它是一个原语,它本质上具有相同的行为,但对于非原语数组,这不容易扩展。我想知道为什么对于int和long,有特定的atomicarray
,但对于其他原语类型,却没有……当然,其他原语可以通过在nAtomicReferenceArray
。我认为AtomicIntegerArray和AtomicLongArray经过优化,可以分别处理integer和long。@JoonasPulakka对于其他基本类型,您也可以使用例如Float.floatToIntBits(Float)将它们转换为int或long
。这避免了在使用AtomicReferenceArray
@Kanagavelu-Sugumar时需要装箱:AtomicReference是一个包装的volatile
,带有一些额外的方法(getAndSet等)。是的,您可以使数组变为volatile。请参阅此-
java.lang.invoke.WrongMethodTypeException: cannot convert MethodHandle(VarHandle,byte[],int,byte)void to (VarHandle,Object[])void
static class Cell<T> {
volatile T elem;
}
private Cell<T>[] alloc(int size){
Cell<T>[] cells = (Cell<T>[]) (new Cell[size]);
return cells;
}
volatile Cell<T>[] arr;
Cell<T>[] newarr = alloc(16);
for (int i = 0; i < newarr.length; i++) {
newarr[i] = new Cell<>();
}
arr = newarr;