Java規範17.5具有下面的代碼來說明使用最終字段在Java存儲模型的。 (相比於普通字段)這不是用Java解釋Final的一個壞例子嗎?
class FinalFieldExample {
final int x;
int y;
static FinalFieldExample f;
public FinalFieldExample() {
x = 3;
y = 4;
}
static void writer() {
f = new FinalFieldExample();
}
static void reader() {
if (f != null) {
int i = f.x; // guaranteed to see 3
int j = f.y; // could see 0
}
}
}
該規範接着說:
「類FinalFieldExample有一個最終詮釋現場x和非最終詮釋字段,Y的 一個線程可以執行。由於writer方法在對象的構造器完成後寫入f,讀者方法將保證看到fx的正確初始化值:它將讀取值3. 但是,fy是不是最終的;讀者的方法因此不能保證看到它的價值4。「
我的問題是:這不是一個跛腳(或至少是一個非常做作)的例子嗎? 還是我失去了一些東西?
我的推理項的實例爲「跛」是:
如果FinalFieldExample類的對象要被通過螺紋在一個多線程的情況下共享,不應該它遵循多線程的基本原則,這是使用某種形式的同步。如果他們使用過同步,那麼提到的問題將不存在。
上述例子似乎主張最終字段作爲適當的同步技術的替代(或部分橡皮奶頭)。根據我的理解,即使在正確的同步之上使用最終字段也是有用的。並且不應該被用來獲得示例中提到的優勢(在沒有同步的情況下)。
所以人們可能要問: 是不是有一個體面的例子(同步於)解釋過正常的域最終場的優勢在哪裏?我猜,不可變性是!
它就是當前內存模型下最終字段發生情況的一個例子。這不是主張你寫這樣的代碼。請參閱JCIP以獲取有關如何編寫併發代碼的建議,其中基本原則是「儘可能使用更高級別的構造(在java.util.concurrent中)」。 –
@NathanHughes:您的評論非常有趣。你能否在JCIP中提供一個參考文件(在使用更高層次的結構時)?謝謝 ! – brainOverflow
嘗試JCIP的這句話,第5章開始:「在實際情況下,委派是創建線程安全類最有效的策略之一:讓現有線程安全類管理所有狀態。」 –