我参加了并发编程课程的考试。这个类结构相当合理,但我觉得我不能理解“volatile”关键字以及我的想法。我已经阅读了其他有关它如何工作的帖子,这看起来很有意义,但我对Java的整体理解限制了我。这些是T / F的练习题,有人会介意回答这些问题并解释为什么它们是真还是假?我在
中做了最好的猜测和解释一个。 _ __ _一个int变量计数在多个线程之间共享, 计数中唯一的操作是读取其值,并增加它。 将计数标记为易失性就足够了。
false,volatile关键字确保此变量没有本地缓存,但仍然会出现争用情况,因为新值取决于前一个计数(因此操作不是原子),因此两个线程可以读取该值,增加它,并且在回写时仍然存在竞争条件。如果count不依赖于先前的值(例如只是写入的ID号),那么这将起作用。
湾 _ ___ 长变量计数在多个线程之间共享, 其中唯一的计数操作是读取其值并增加 它。将计数标记为易失性就足够了。
与上面相同,除非该值不依赖于先前的值,否则这不是线程安全的,因为它绝不是原子操作,因为long需要两个写周期用于上部和下部32位写入和读取
℃。 _ ___ 布尔变量b,最初为false,在它们之间共享 多线程。一个特定的线程将其值设置为true,另一个 线程读取值。将b标记为易失性就足够了。
是的,更改布尔值是原子的,可以在中断发生之前发生,并更新所有其他线程。
d。 _ ___ 布尔变量b在多个线程之间共享。 任何线程都可以设置或读取其值。一旦b设置为true,它仍然是真的 今后。将b标记为易失性就足够了。
是的,与上述原因相同。
非常感谢!
答案 0 :(得分:5)
一个。你的答案很好(即挥发性不够)
湾“它永远不是原子操作,因为长时间需要两个写周期用于上部和下部32位写入和读取”=>这对于非易失性变量来说太强了:非易失性长赋值可能是也可能不是原子的。它通常是64位处理器上的原子,但Java内存模型不提供任何保证。但是,保证长波动的长期分配是原子的。
℃。你的答案很好(虽然我不明白你的意思是“在中断发生之前”)
d。你的答案很好
答案 1 :(得分:2)
e:布尔值var,最初为false,任何线程都可以设置为true,但只能设置一次。
这称为共识问题:线程如何选择其中哪一个设置标志?在这种情况下,仅靠挥发性是不够的。
共识问题是理解多处理的基础。如果你无法解决共识问题,那么你就不能互斥,你不能拥有多个消费者队列或多个提供者队列,......如果你无法解决共识问题,那么你真的可以' t提供任何正确的保证。
问题D的作者是否有共识问题?当你的回答限于T或F时,这是一个艰难的要求。