[英]Is a java synchronized method entry point thread safe enough?
我有一個Singleton類處理一種Hashmap中具有不同對象的緩存。 (鍵的格式直接鏈接到地圖中存儲的對象類型 - 因此地圖是)
地圖上可以執行三種不同的操作:添加,獲取,刪除。
我使用公共入口點方法(沒有密集訪問)來保護對地圖的訪問:
public synchronized Object doAction(String actionType, String key, Object data){
Object myObj = null;
if (actionType.equalsIgnorecase("ADD"){
addDataToMyMap(key,data);
} else if (actionType.equalsIgnorecase("GET"){
myObj = getDataFromMyMap(key);
} else if (actionType.equalsIgnorecase("REM"){
removeDataFromMyMap(key);
}
return myObj;
}
筆記:
地圖是私人的。 方法addDataToMyMap(),getDataFromMyMap()和removeDataFromMyMap()都是私有的。 只有入口點方法是公共的,除了類本身的靜態getInstance()之外別無其他。
您是否確認並發訪問地圖是線程安全的,因為沒有其他方法可以使用地圖但通過該方法?
如果它是Map的安全,我想這個原則可以應用於任何其他類型的共享資源。
非常感謝你的答案。
大衛
我需要看看你的方法的實現,但它可能就足夠了。 但我建議你使用java的Collection API中的Map,然后除非你共享其他實例,否則你不需要同步你的方法。
閱讀: http : //www.java-examples.com/get-synchronized-map-java-hashmap-example
是的,只要唯一的入口點是doAction,您的類就是線程安全的。
如果您的cache
類具有私有HashMap
並且您有三個方法並且所有方法都是public synchronized
而不是static
並且如果您沒有任何其他public
實例變量,那么我認為您的緩存是thread-safe
。
最好發布您的代碼。
這是完全安全的。 只要所有線程都使用公共鎖訪問它,在這種情況下是對象,那么它是線程安全的。 (其他答案可能更高效,但您的實施是安全的。)
您可以使用Collections.synchronizedMap來同步對Map
訪問。
因為很難確定代碼是否是線程安全的。 您的示例中缺少的重要信息包括:
我建議你研究同步 ,以掌握問題以及如何解決它們。 探索ConcurrentHashMap類將提供有關您的問題的更多信息。
您應該使用ConcurrentHashMap 。 與Collections.synchronizedMap()相比,它提供了比同步doAction更好的吞吐量和更好的線程安全性。
這取決於您的代碼。 正如其他人所說,您可以使用Collections.synchronizedMap。 但是,這只會同步地圖上的各個方法調用。 因此,如果:
map.get(key);
map.put(key,value);
在兩個不同的線程中同時執行,一個將阻塞,直到另一個退出。 但是,如果您的關鍵部分大於對地圖的單個調用:
SomeExpensiveObject value = map.get(key);
if (value == null) {
value = new SomeExpensiveObject();
map.put(key,value);
}
現在讓我們假設密鑰不存在。 第一個線程執行,並返回null值。 調度程序產生該線程,並運行線程2,線程2也返回空值。 它構造新對象並將其放入地圖中。 然后線程1恢復並執行相同的操作,因為它仍然具有空值。
這是您需要圍繞關鍵部分的更大同步塊的地方
SomeExpensiveObject value = null;
synchronized (map) {
value = map.get(key);
if (value == null) {
value = new SomeExpensiveObject();
map.put(key,value);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.