【发布时间】:2019-08-26 02:54:02
【问题描述】:
在我正在开发的应用程序中,我发现了以下代码 sn-p:
public class MyClass {
private AtomicBoolean atomicBoolean = new AtomicBoolean(false);
public void Execute() {
// Whole lot of business logic
// ....
synchronized (this.atomicBoolean) {
// Want to make sure that execution is stopped if Stop() was called
if (this.atomicBoolean.get()) {
throw new SpecificException("...");
}
// Some more business logic...
}
}
public void Stop() {
synchronized (this.atomicBoolean) {
this.atomicBoolean.set(true);
}
}
}
根据 FindBugs 的说法,这是不正确的,因为我不能同时使用 AtomicBoolean 和 synchronized 并期望它阻止对象。
我的问题是:重写此方法的正确方法是什么?我已经阅读了有关将锁定对象与布尔属性一起使用的信息,但是为该锁定引入两个新属性似乎有点笨拙。
编辑:正如下面的评论中所述:我认为目的是在两个 synchronized 块中,AtomicBoolean 不能更改,而一个线程在 synchronized 块之一中,没有其他这样的块可以输入。
【问题讨论】:
-
是的,同步并不能阻止
AtomicBoolean在其他地方被更改,但是要就如何修复它给出一个好的建议,我们需要知道这些方法还试图做什么。 -
为什么不让这两个方法同步呢?那将等同于您似乎想要做的事情。
-
你为什么还要在这里使用
synchronized。从表面上看,这是完全没有必要的,因为AtomicBoolean已经是原子的并且在没有锁定的情况下具有必要的可见性保证(并且锁定可能会导致更差的性能),所以请解释你的原因和你想要实现的目标,以便我们解释你的想法是错误的(或正确的)。在所示代码中,您最好使用普通的boolean变量而不是AtomicBoolean。 -
虽然将原子变量与
synchronized一起使用看起来很可疑,但我想知道 FindBugs 是专门针对这种组合,还是只是抱怨atomicBoolean没有被声明为final。后者很容易解决。 -
嗯,是的,关于混乱是正确的。在这里,就您的示例所示而言,您可以使用不带
AtomicBoolean的synchronized或不带synchronized的AtomicBoolean,它仍然可以工作。事实上,private volatile boolean stop;也可以。
标签: java multithreading java-8 synchronized atomicboolean