我在 Java 中有一个原子布尔属性
private AtomicBoolean endOfInputDataSet;
该属性的正确 getter 和 setter 是什么?每个选择的后果是什么?AtomicBoolean
我可以直接退货
public AtomicBoolean getEndOfInputDataSet() {
return this.endOfInputDataSet;
}
public void setEndOfInputDataSet(AtomicBoolean endOfInputDataSet) {
this.endOfInputDataSet = endOfInputDataSet;
}
或者我可以退回未包装的boolean
:
public boolean getEndOfInputDataSet() {
return this.endOfInputDataSet.get();
}
public void setEndOfInputDataSet(boolean endOfInputDataSet) {
this.endOfInputDataSet.set(endOfInputDataSet);
}
我认为后一种解决方案只是让客户端使用起来更简单、更干净,但是为什么 IntelliJ 生成 getter 和 setter 时不是默认的呢?
太长了;博士
👉🏽 共享
Atomic…
对象容器,而不是其有效负载值。共享
AtomicBoolean
对对象的访问为了让多个线程围绕对象有效负载中包含的值进行协调
Atomic…
,线程必须同时直接访问Atomic…
对象本身。不要共享该值的副本
AtomicBoolean
将值的副本发送到各个线程破坏了使用
Atomic…
类所预期的交互的原子性质。制作有效负载值的副本不是线程安全的,线程现在无法围绕单个值进行协调。细节
这样做是
final
为了防止AtomicBoolean
分配另一个对象来替换原始对象。您也可以在声明中实例化。
原子…对象是携带有效负载的容器,同时提供对该有效负载的线程安全访问。
该行返回对该容器的引用。然后,调用程序员可以获取或设置该有效负载的内容。
这条线破坏了你的场景。您允许调用程序员替换您的容器。
此行返回容器内容的副本。
请注意,这一行的方法正在返回“旧消息”。
get()
在调用结束和调用程序员实际收到值之间有一个时间节拍。在此节拍期间,另一个线程可能已set
在原子容器上执行了 a,从而更改了容器的内容。您已经撤消了 中的“原子”AtomicBoolean
。这段代码不是线程安全的。(a) 接收我们返回的负载值副本的调用方法与 (b) 使用该值的调用方法之间还有更多的时间节拍。在这些额外的节拍期间,对象中的调用实际负载
AtomicBoolean
可能会发生变化。与上面的行一样,该行也是非原子且线程不安全的。
因为这样的代码不是线程安全的。
当尝试围绕单个值协调多个线程时,这些线程必须同时处理相同的值,该值作为原子包装器中的有效负载携带。为了实现这一点,所有线程必须直接处理原子包装容器。
因此,您实际上并不需要这里的 getter/setter 访问器方法。只需使原子对象
final
可直接访问(public
等等)。想象一下教室里的一群孩子试图围绕信封中的信息协调他们的活动。如果你让不同的孩子复制该消息,而其他孩子正在更改该消息,那么你就会陷入混乱。为了协调孩子们的活动,他们必须同时查看信封中携带的唯一信息。