0
public class Status {

    private Scheduler scheduler;
    private volatile Boolean lastResult;

    public Status() {
        scheduler = new Scheduler();
        scheduler.everyTenSeconds(new Action());
    }


    public boolean isSth()  {
        if (lastResult != null && lastResult) {
            return lastResult;
        } else {
            return checkSth();
        }
    }


    private boolean checkSth() throws SomeException {
        // checking sth
    }

    private class Action implements Runnable {

        @Override
        public void run() {
            try {
                lastResult = checkSth();
            } catch (SomeException e) {
                lastResult = false;

            }

        }
    }
}

调用外部类变量是线程安全的吗?最后一个结果是 lastResult 但在调用 isSth() 时 lastResult 始终为空。尽管 run 被调用了两次。

4

1 回答 1

0

线程安全调用外部类变量吗?

一般来说,它既不是线程安全的,也不是线程安全的。线程安全取决于您实际执行的操作。

而且......严格正确......你不能调用变量:

  • 您可以读取变量的值。
  • 如果变量的值是一个对象,那么您可以调用该对象的实例方法。

在您的示例中,代码正在执行涉及 volatile 的操作序列。对 volatile 的单个读取或写入操作是原子的,并且在 Java 内存模型方面具有明确定义的属性。但是,一系列操作不是原子的,而且 JMM 属性很复杂。

长话短说,您的代码正在执行一系列读写操作,lastResult并且不是线程安全的。


但是,尽管如此,我看不出您的代码如何/为什么始终lastResult设置为null. 我怀疑这与您使用此代码的方式有关。我们真的需要一个 MCVE;即一个完整可执行的示例,我们可以运行它来查看您所看到的行为。

于 2017-09-18T12:56:48.877 回答