我想了解這是否是線程安全的。我相信是這樣,但最近有人質疑這種方法的線程安全性。瞭解線程安全
比方說,我有一些工廠FactoryA
,讓我們它實現了以下接口的類:
public abstract class MyFactory {
private ObjectA object;
public void init(ObjectA object){
_object = object;
}
}
因此,我們必須像
public class FactoryA extends MyFactory {
static final createFactoryClass(String name) {
// ...ignorning safety checks for brevity
return MY_MAP.get(name).newInstance();
}
}
現在,我已經在另一個一些方法返回可能類別的地圖:
public class OtherClass {
private static FactoryA _factory = new FactoryA();
private static final Map<String, SomeClass> MY_MAP = new ImmutableMap.Builder<String, MyClass>()
.put("foo", _factory.createFactoryClass("foo"));
private SomeObject myMethod(ObjectA objectA, SomeObject someObject) {
MY_MAP.get(someObject.getString()).init(objectA);
}
}
問題是init
方法是否是線程安全的。該映射只初始化一次,所以即使它存儲在一個不可變的結構中,如果兩個線程使用不同的ObjectA
調用它,錯誤的類是否可能使用錯誤的ObjectA
?
我可以通過執行以下操作來解決這個問題嗎?
private static synchronized myMethod(...) {}
這是有點令人困惑,因爲代碼中你引用的對象跨類和類型不匹配。但我認爲真正的問題在於你在'init'方法中做了什麼? – Xerillio
您的'MyFactory.init'方法,就像給出的那樣,完全是線程安全的,因爲它什麼都不做。 –
'createFactoryClass()'看起來也是線程安全的。正如你所說,你初始化地圖一次,然後再寫一次。這裏的附帶條件是它仍然必須可見;將它分配給'final'就可以了,並且使地圖(和所有的寫入)可見,就像'volatile'和'synchronized'一樣。 C.F. [「安全出版物」](http://stackoverflow.com/questions/801993/java-multi-threading-safe-publication) – markspace