3

在我正在开发的应用程序中,我发现了以下代码片段:

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块中时,不能输入其他这样的块。

4

2 回答 2

8

只需替换synchronized (this.atomicBoolean) {两种方法中的部分,AtomicBoolean::get并且AtomicBoolean::set已经是原子的。

于 2019-04-04T11:11:36.310 回答
1

...我不能将 AtomicBoolean 与 synchronized 一起使用...

无论价值如何,该语言都允许您在任何对象上进行同步。

作为风格问题,一些程序员更喜欢只在不用于其他目的的私有对象上进行同步。

private static Object foobarLock = new Object();
...
public void fooItUp(...) {
    ...
    synchronized(foobarLock) {
        ...
    }
    ...
}

...并期望它阻止对象

需要明确的是,当某个线程 T 进入一个synchronized (o) {...}块时,这不会阻止其他线程访问或修改该 object o。它唯一阻止的是,它阻止了一些其他线程 U 同时进入同一对象o上的同步块。

于 2019-04-04T13:45:47.947 回答