如何在Java中声明数组元素为易失性?
有没有办法在Java中声明数组元素易失性
?即
volatile int[] a = new int[10];
声明数组引用 易失性
,但数组元素(例如a[1]
)仍然不是易失性的。所以我正在寻找类似的东西
volatile int[] a = new volatile int[10];
,但它不会那样工作。有可能吗?
Is there a way to declare array elements volatile
in Java? I.e.
volatile int[] a = new int[10];
declares the array reference volatile
, but the array elements (e.g. a[1]
) are still not volatile. So I'm looking for something like
volatile int[] a = new volatile int[10];
but it doesn't work that way. Is it possible at all?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
使用
AtomicIntegerArray
或AtomicLongArray
或AtomicReferenceArray
AtomicIntegerArray
类实现一个 int 数组,其各个字段可以通过易失性语义进行访问,通过类的get()
和set()
方法。从一个线程调用 arr.set(x, y) 将保证另一个调用 arr.get(x) 的线程将读取值 y(直到读取另一个值)到位置 x)。请参阅:
Use
AtomicIntegerArray
orAtomicLongArray
orAtomicReferenceArray
The
AtomicIntegerArray
class implements an int array whose individual fields can be accessed with volatile semantics, via the class'sget()
andset()
methods. Callingarr.set(x, y)
from one thread will then guarantee that another thread callingarr.get(x)
will read the value y (until another value is read to position x).See:
不,你不能使数组元素变得易失。另请参阅 http://jeremymanson.blogspot.com/2009/06 /volatile-arrays-in-java.html 。
No, you can't make array elements volatile. See also http://jeremymanson.blogspot.com/2009/06/volatile-arrays-in-java.html .
另一种方法是使用 JDK 9+
VarHandle
类。正如您在Atomic
xxxArray
类的源代码中看到的,例如AtomicIntegerArray
,从 JDK 9 开始,这些类也使用VarHandle
:首先创建一个
VarHandle
,如下所示:例如,您可以输入
byte[].class
在这里自行实现缺少的AtomicByteArray
。然后您可以使用
set
xxx(array, index, value)
和get
访问它xxx(array, index)
方法,其中array
的类型为yourArrayClass
,index
的类型为typeint
,value
是数组中元素的类型 (yourArrayClass.getComponentType()
)。请注意,例如,如果
yourArrayClass == byte[].class
但您输入42
作为value
,则会收到错误,因为42
是一个int
而不是byte
,访问方法的参数是 varargObject...
参数:(第二个签名是您使用的签名,第一个签名是您应该使用的签名。)
请注意,在 JDK 8 及以下版本
sun.misc.Unsafe
来实现原子类,例如AtomicIntegerArray
:使用
Unsafe
仍然是一个选择(尽管我认为获得它有点棘手一个实例),但不鼓励这样做,因为您必须自己检查数组边界,如果您犯了错误,它可能会导致 Java 进程出现段错误,而VarHandle
会为您进行边界检查,并在以下情况下抛出 Java 异常:给定的索引超出范围(但这可能会带来性能成本)。除此之外,Unsafe
不受官方支持,可能随时被删除。但从 JDK 10 开始,
AtomicInteger
因为'未解决的循环启动依赖项”。如果您想了解有关可用的不同 get 和 set 方法的更多信息,请查看 使用JDK 9 内存顺序模式(我不得不说我根本不是这方面的专家(还?))。
请注意,从今天开始,您无法在 Kotlin 中使用VarHandle
,因为它将 get 和 set 方法的 varargObject...
参数包装在中Object[]
,请参阅 bug KT-26165:(现在应该修复)Another way to do this is using the JDK 9+
VarHandle
class. As you can see in the source code of theAtomic
xxxArray
classes likeAtomicIntegerArray
, these classes also useVarHandle
since JDK 9:You first create a
VarHandle
like this:For example, you can enter
byte[].class
here to implement the missingAtomicByteArray
yourself.And then you can access it using the
set
xxx(array, index, value)
andget
xxx(array, index)
methods, wherearray
is of typeyourArrayClass
,index
is of typeint
,value
is of the type of an element in your array (yourArrayClass.getComponentType()
).Note that if, for example,
yourArrayClass == byte[].class
but you enter42
asvalue
, you get an error because42
is anint
instead of abyte
and the parameters of the access methods are varargObject...
parameters:(The second signature is the one that you used, the first one is the one that you should have used.)
Note that in JDK 8 and below
sun.misc.Unsafe
was used to implement the atomic classes likeAtomicIntegerArray
:Using
Unsafe
is still an option (although I think it's a bit tricky to obtain an instance), but it is discouraged because you have to check array bounds yourself and it might segfault the Java process if you make a mistake, whileVarHandle
does bounds checks for you and throws a Java exception if the given index is out of bounds (but that may come with a performance cost). Besides that,Unsafe
is not officially supported and might be removed at any time.But as of JDK 10
Unsafe
is still used inAtomicInteger
because of 'unresolved cyclic startup dependencies'.If you want to know more about the different get and set methods available, take a look at Using JDK 9 Memory Order Modes (I have to say that I'm not an expert in this at all (yet?)).
Note that as of today you cannot useVarHandle
in Kotlin, because it wraps the varargObject...
parameters of the get and set methods in anObject[]
, see bug KT-26165:(should be fixed now)怎么样:
细胞也会使内容物变得不稳定。另外,我仅在预分配单元之后才将新数组分配给易失性数组...存在单元额外内存的权衡,但它是可以管理的
How about this:
the cells make the content volatile too. also I assign the new array to the volatile one only after pre allocating the cells... there's the trade off of the Cell extra memory, but it's manageable