2010-04-20 60 views
3

我正在擴展一個庫來爲我做一些工作。這裏是代碼:Java靜態和線程安全性或做什麼

public static synchronized String decompile(String source, int flags,UintMap properties,Map<String,String> namesMap) 
    { 
     Decompiler.namesMap=namesMap; 
     String decompiled=decompile(source,flags,properties); 
     Decompiler.namesMap=null; 
     return decompiled; 

    } 

問題是namesMap是靜態變量。線程是否安全?因爲如果這個代碼一致地運行namesMap變量可能會改變。我能爲此做些什麼?

+0

是否在代碼中的其他地方訪問了namesMap?如果是這樣,你能舉一個具體的例子嗎? – Finbarr 2010-04-20 16:26:03

+0

它會從另一個反編譯()只訪問.. – GorillaApe 2010-04-20 16:27:18

回答

5

方法decompile是線程安全的(它永遠不會被兩個線程同時運行),但如果什麼除此之外方法也使用namesMap,則沒有,總體而言,這不是線程安全的:另一種方法其他decompile運行在不同的線程可以修改地圖而decompile方法正在使用它,大概造成混亂。 :-)

您可以查看java.util.concurrent命名空間中的類(例如,ConcurrentHashMap),以查看這些類中的任何一個是否適用於您正在執行的操作。

編輯(響應您的評論。)如果靜態成員namesMap只用過通過decompile,而不是由其他任何(你不會對它的引用到別的,等等),那麼你很好。它是一個靜態的事實並不重要,如果它唯一使用的地方是序列化的。

+0

而且「* only ever used *」意味着有一天,另一個開發人員會忘記這個隱式的需求,並在別處使用它,你會得到虛假的錯誤。 – 2010-04-20 16:32:46

+0

如果僅在一個地方使用靜態成員'namesMap',爲什麼不將其從靜態成員更改爲方法參數呢?這樣你可以消除所有疑問。 – 2010-04-20 16:50:09

+0

@Aaron:絕對。 – 2010-04-20 16:56:03

1

如果有其他線程在如上所述的方法正在運行的情況下對namesMap進行更改的機會,那麼您應該製作傳入地圖的副本,而不是僅分配參考。

Decompiler.namesMap= new HashMap<String, String>(namesMap); 

如果有機會的話,其他線程將更改包含在地圖內的元素,而不僅僅是地圖本身的結構,那麼你應該確保你的decompile()法和其他使用namesMap的線程由相同的鎖保護。

0

其實Decompiler.namesMap=namesMap; 是設置namesMap

但無處可在namesMap改變的代碼.. 只讀我想確保的唯一的地方...

String decompiled=decompile(source,flags,properties); 

將使用相同的名稱映射。

0

只會有一個名稱映射,所以您不必擔心它是否使用相同的名稱映射。它會。