2

I have code similar to following:

class OuterClass
{
   private final AtomicInteger count = new AtomicInteger(0);

   private class InnerClass extends TimerTask
   {
       public void run()
       {
            ......
            ......
            incremenetCount();
       }
   }

   public void doSomething()
   {
        .......
        .......
        incremenetCount();
   }

   private void incrementCount()
   {
      count.incrementAndGet();
   }
}

Is calling incrementCount from inner class the same as calling it from any other function in outer class as the synchronization is actually around the variable count?

4

2 回答 2

5

Is calling incrementAndCount from inner class the same as calling it from any other function in outer class [...]

Yes, calling incrementCount() from the inner class is the same as calling incrementCount() from the outer count.

All non-static inner classes have an implicit reference to the object of the enclosing class, and it is through this reference the incrementCount() will be called.

(Story would have been different if your inner class was static though.)

as the synchronization is actually around the variable count?

Doesn't matter. The same method, is called on the same object, regardless if you do the call from the inner or from the outer class.

于 2012-04-25T04:46:32.047 回答
3

简短的回答是它是安全的。

要了解原因,让我们看一下:

class SomeClass {
    private final AtomicInteger count = new AtomicInteger(0);
    ...
    private void incrementCount() {
        count.incrementAndGet();
    }
}

需要考虑两个问题来确定这是否是线程安全的。

  1. 获取count是否正确同步?回答是 - 因为count被声明为final并且有规则说final一旦构造函数完成就可以在不同步的情况下读取字段。

  2. incrementAndGet()方法是线程安全的吗?回答是 -AtomicInteger类的规范是这样说的。

现在让我们看一下内部类的情况。内部类的实例对外部类的实例有一个隐藏的最终引用。所以 ...

    public void run() {
        incrementCount();
    }

相当于这个...

    private final OuterClass $outer;  // initialized by the constructor.
    ...
    public void run() {
        $outer.incrementCount();
    }

根据上面第 1 点的推理,incrementCount()调用本身是线程安全的。并且 fetch$outer也是线程安全的,因为它隐含地是一个final字段。

于 2012-04-25T05:21:34.157 回答