我在一个并发编程课上有一个考试。这门课结构相当好,但我觉得我对“易失性”关键词的理解一定没有我想象的那么好。我已经通读了其他关于它是如何工作的帖子,这似乎是有意义的,但是我对Java整体的理解限制了我。这些是练习题,有人介意回答它们并解释为什么它们是真的或假的吗?我已经把我最好的猜测和解释
A.____Anint变量计数在几个线程之间共享,其中计数的唯一操作是读取其值并将其递增。将计数标记为易挥发就足够了。
false,volatile关键字确保此变量没有本地缓存,但竞争条件仍然可能发生,因为新值取决于前一个for count(因此操作不是原子的),因此两个线程可以读取该值,增加它,并且在写回时仍然存在竞争条件。如果计数不依赖于之前的值(例如,只写一个ID号),这将起作用。
b、 ____;长变量count在多个线程之间共享,其中对count it的唯一操作是读取其值并增加它。只需将计数标记为不稳定即可。
如上所述,除非该值不依赖于以前的值,否则这不是线程安全的,因为它从来不是原子操作,因为高32位和低32位写入和读取需要两个写入周期
c、 ___;布尔变量b最初为false,在多个线程之间共享。一个特定线程将其值设置为true,其他线程读取该值。将b标记为挥发性就足够了。
确实,更改布尔值是原子的,可以在中断发生之前进行,并更新所有其他线程。
d、 布尔变量b在多个线程之间共享。任何线程都可以设置或读取其值。一旦b被设置为true,它将保持true。将b标记为挥发性就足够了。
没错,原因和上面一样。
非常感谢!
问题D让我想起了为什么我讨厌T/F问题。这看起来很像问题C,但是,如果你稍微改变一下,这将是一个完全不同的、有趣的问题:
e:Boolean var,最初为false,任何线程都可以将其设置为true,但只能设置一次。
这就是所谓的共识问题:线程如何选择其中哪一个来设置标志?在这种情况下,仅仅挥发性是不够的。
共识问题是理解多重处理的基础。如果你不能解决共识问题,那么你就不能有互斥,你不能有多个消费者队列或多个提供者队列,...如果你不能解决共识问题,那么你真的根本无法提供任何正确性保证。
问题D的作者是否考虑了共识问题?当你的回答仅限于T或F时,这是一个很难做出的决定。
b、 “它从来不是一个原子操作,因为long需要两个写入周期来完成上32位和下32位的写入和读取。”=
c、 你的回答很好(尽管我不明白你所说的“在中断发生之前”是什么意思)
D.你的答案很好
我正在从Java过渡到C,对<code>long</code>数据类型有一些疑问。在Java中,要保存大于2的整数<sup>32<sup>,只需编写<code>长x 。然而,在C语言中,<code>long</code>似乎既是数据类型又是修饰符。 似乎有几种方法可以使用: 还有,好像还有这样的事情: 等等 所有这些不同的数据类型之间有什么区别,它们都有相同的目的吗?
如果和在一个平台上的表示形式相同,那么它们是严格相同的吗?根据C标准,这些类型在平台上的行为是否有任何不同? 这样做总是有效的吗: 我猜同样的问题也适用于short和int,如果它们碰巧是相同的表示。 在讨论如何为没有stdint.h的嵌入式C89编译器定义类似的typedef(即或)以及这是否重要时,出现了这个问题。
问题内容: 我最近在一次演讲中听说,对volatile的写操作会为线程已写入的每个变量触发内存屏障。真的对吗?从JLS看来,似乎只有相关的变量被清除了,而其他变量则没有。有人知道什么是正确的吗?能否给我指出JLS中的具体位置? 问题答案: 对挥发性变量和其他变量的引用是正确的。我没有意识到,before- before的可传递性是VM必须实现的,而不是从定义中得出的。我仍然感到困惑,为什么并没有明
问题内容: 是否有可能创造 ; 我的意思是将来自不同类的对象添加到一个arraylist? 谢谢。 问题答案: 是的,有可能: 该列表将接受任何实现的对象。
问题内容: Java 中(primitive)和(primitive wrapper)的默认值是什么? 问题答案: (对象)的默认值为。(原始) 的默认值为。
描述 (Description) C库函数long int labs(long int x)返回long int labs(long int x)的绝对值。 声明 (Declaration) 以下是labs()函数的声明。 long int labs(long int x) 参数 (Parameters) x - 这是整数值。 返回值 (Return Value) 此函数返回x的绝对值。 例子