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

时间:2017-09-18 12:21:05

标签: java multithreading inner-classes outer-classes

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始终为null。尽管跑了两次。

1 个答案:

答案 0 :(得分:0)

  

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

通常,它既不是线程安全的,也不是线程安全的。线程安全取决于您实际执行的操作。

并且......严格地说......你不能调用变量:

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

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

简而言之,您的代码在lastResult上执行读写操作序列,并且不是线程安全的。

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