繁体   English   中英

赋值和函数值计算是原子操作吗?

[英]Is assignment and function value calculation an atomic operation?

我想知道函数值的计算以及将结果分配给变量是否在Java中是原子操作。

例如:

我有一个线程安全优先级队列q q我保存元素,每个元素都有一个根据其在队列中放置的rank 另外,我有一个共享变量topRank ,该变量应始终包含q最顶层元素的等级。 以下代码按线程数并行执行:

element = q.remove(); // do something with element
topRank = q.peek();

可能发生的情况是threadA将从q删除一个元素并计算q.peek()值,就在将其分配给topRank之前, topRank会中断它,然后threadB将从q删除另一个元素并更新topRank 然后的ThreadA将恢复到不正确的值到分配topRank

与官方文献的链接将不胜感激。

谢谢。

简短的答案是这些操作不是原子操作,您需要将同步写入代码中。 这是一个巨大的主题,有关编写线程安全程序的知识很多。 Google表示“ java线程安全”和“ java多线程”。

线程安全性只是指操作 remove()peek()调用。 除非您采取措施阻止线程相互竞争, topRank使用topRank是完全可能的。

有关更多信息,请参阅Java同步教程

1)我认为没有原子操作,除非您保护它们(同步和其他技术)。

2)也就是说,它不适用于您的示例。

在您的示例中,您有。

a)致电q.remove()

b) q.remove()完成其工作(是否线程安全)。

c) q.remove()返回结果

d)将结果分配给element (这是分配!!!!!!!!!!)


因此,不仅分配(操作的最后一步)是否是原子的,还需要确保q.remove()也是原子的。 我向您保证不是。

由于它不是线程安全的,因此如果要避免并发访问,则应同步整个块。


编辑回答作者的评论。

因此,您要问的是, q.peek()是否会以某种方式返回一个元数据,但另一个会由于其他线程将其topRank而以topRank结尾,不是吗?

除非不同线程共享topRank ,否则不可能:

a) q.peek()运行其逻辑

b)复制q.peek() )的返回值(存储在堆栈中,返回到名为q.peek()表达式)

c) q.peek()退出。 现在只有其他实例可以访问同步部分以更改q.state,但是返回值已复制到堆栈中。

d)将堆栈中的副本分配给topRank

函数值的计算不可能是原子的。 该函数在返回值之前可以运行数年。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM