2011-08-21 75 views
1

考虑第三方类像其他线程可以看到继承的非final字段吗?

class A { 
    private int value; 
    public int getValue() { 
     return value; 
    } 
    public void setValue(int value) { 
     this.value = value; 
    } 
} 

我让一成不变像

final class ImmutableA extends A { 
    public ImmutableA(int value) { 
     super.setValue(value); 
    } 
    public void setValue(int value) { 
     throw new UnsupportedOperationException(); 
    } 
} 

visibility guarantee for final fields在这里并不适用。我的问题是,如果其他线程保证看到ImmutableA的正确状态。

如果没有,是否有解决方案?使用委派不是一种选择,因为我需要ImmutableAA

回答

0

你可以使用​​,虽然这可能在吸气慢下来:

final class ImmutableA extends A 
{ 
    public ImmutableA(int value) { 
     synchronized (this) { 
      super.setValue(value); 
     } 
    } 

    public void setValue(int value) { 
     throw new UnsupportedOperationException(); 
    } 

    public synchronized int getValue() { 
     return super.getValue(); 
    } 
} 
1

是的,如果你使用volatile这有写它的保障是可见的其他线程

class A { 
    private volatile int value; 
    public int getValue() { 
     return value; 
    } 
    public void setValue(int value) { 
     this.value = value; 
    } 
} 
+0

对不起,我应该更清楚地提到这一点:'A'是我不能修改的第三方类。 – maaartinus

+0

另一种在构造函数中添加同步块的方式,但这只是解决方案的一半,如果使用external [发生前](http://download.oracle.com/javase/6/docs/api/java/ util/concurrent/package-summary.html#MemoryVisibility)保证那么它是可见的 –

0

受starblue的回答启发,我找到了一个不使用同步的解决方案。它结合了代表团继承:

final class ImmutableA extends A { 
    private final ImmutableA that; 

    public ImmutableA(int value) { 
     super.setValue(value); 
     that = this; 
    } 

    public void setValue(int value) { 
     throw new UnsupportedOperationException(); 
    } 

    private int superGetValue() { 
     return super.getValue(); 
    } 

    public int getValue() { 
     return that.superGetValue(); 
    } 
} 

我想应该是因为final知名度保证工作。但我不认为这是值得的麻烦。所有的方法都需要重写和重复,因为那个.getValue()会导致无限递归,并且that.super.getValue()(或super.that.getValue())是非法的。

相关问题