[英]How to make Java function atomic operation, and prevent calculation main thread interruption for handing results from another thread
[英]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.