我知道您可以通過編寫對final
或volatile
字段的引用來安全地發佈非線程安全對象,該字段稍後將由另一個線程讀取,前提是發佈時線程創建該對象的對象會放棄對其的引用,以便它不再幹擾或不安全地觀察該對象在另一個線程中的使用。本地最終引用的安全發佈
但是在這個例子中,沒有明確的final
字段,只有final
局部變量。 如果來電者丟棄了對unsafe
的引用,這是否安全發佈?
void publish(final Unsafe unsafe) {
mExecutor.execute(new Runnable() {
public void run() {
// do something with unsafe
}
}
}
我發現了幾個Q &作爲,像this one,這表明final
局部變量是隱式「複製」到匿名類。這是否意味着上面的例子等同於這個?
void publish(final Unsafe unsafe) {
mExecutor.execute(new Runnable() {
final Unsafe mUnsafe = unsafe;
public void run() {
// do something with mUnsafe
}
}
}
編輯澄清:
Unsafe
可以是任何東西,但說這是這樣的:
public class Unsafe {
public int x;
}
而且mExecutor
是什麼,滿足Executor
合同。
您的執行程序正在使用線程安全隊列。要看到這個問題,你必須在線程之間傳遞對象,而不用在任何地方使用合適的內存屏障 –
@PeterLawrey class Executor {void execute(Runnable r){}}' - 這裏沒有隊列。但問題是*可能*有效還是... – Marco13
BTW'Unsafe'是具有一個單類,雖然你可以創建更多的人... –