類A
的方法由兩個線程訪問。一個線程更新它。另一個檢索其成員。通過訪問器檢索實例成員的線程安全
public class A {
private V v;
public V getV() {
return v;
}
public V updateV(A a, B b, Cc) {
//complex logic updating V
}
}
我該如何讓V
線程安全?
類A
的方法由兩個線程訪問。一個線程更新它。另一個檢索其成員。通過訪問器檢索實例成員的線程安全
public class A {
private V v;
public V getV() {
return v;
}
public V updateV(A a, B b, Cc) {
//complex logic updating V
}
}
我該如何讓V
線程安全?
使V
線程安全的最簡單的方法是讓不變(通過使最終所有的非靜態字段),然後在A
只需在updateV
作爲未來影響V
一個新實例:
public class A {
private V v;
public synchronized V getV() {
return v;
}
public synchronized V updateV(A a, B b, Cc) {
//complex logic updating V
this.v = new V(...);
return v;
}
}
正如你可以看到使A
線程安全的,我只是添加關鍵字吸氣劑,防止併發讀寫,但如果你的情況是不是需要它,你可以門坎使v volatile
在明年的二傳:
public class A {
private volatile V v;
public V getV() {
return v;
}
public V updateV(A a, B b, Cc) {
//complex logic updating V
this.v = new V(...);
return v;
}
}
如果您只使用同步版本,則不會保證該字段不再位於緩存中。在這種情況下,您應該使用volatile來確保可見性。 –
@NicolasHenneaux我不這麼認爲,你使用同步或不穩定不檢查,例如類Vector的代碼(或基於同步的任何線程安全類),你會看到代表狀態的所有字段都不易揮發 –
Your在同一對象(本例中爲實例)上使用同步關鍵字會導致內存障礙(請參閱https://stackoverflow.com/questions/3519664/difference-between-volatile-and-synchronized-in-java)。 –
請提供V –
的代碼是否正在更新** V的現有實例還是正在創建一個替換舊實例的新實例? – Fildor
您能否從getter返回'v'的防禦副本,還是必須在所有以前返回的實例中都可見? –