// Singleton
public static final Map<String, Account> SHARED_ACCOUNT_HASHMAP =
Collections.synchronizedMap(new HashMap<>());
public init(String[] credentials) {
Account account = null;
String uniqueID = uniqueAccountIdentifier(credentials);
if (SHARED_ACCOUNT_HASHMAP.containsKey(uniqueID)) {
account = SHARED_ACCOUNT_HASHMAP.get(uniqueID);
log("...retrieved Shared Account object: %s", uniqueID);
}
// create the Account object (if necessary)
if (account == null) {
account = new Account(credentials);
// Store it in the SHARED_ACCOUNT_HASHMAP
SHARED_ACCOUNT_HASHMAP.put(uniqueID, account);
log("...created Account object: %s",uniqueID);
}
}
init()
方法并运行一次。答案 0 :(得分:1)
返回由指定映射支持的同步(线程安全)映射。为了保证串行访问,必须通过返回的映射完成对支持映射的所有访问。
当迭代任何集合视图时,用户必须手动同步返回的地图
换句话说,您仍然需要synchronized
SHARED_ACCOUNT_HASHMAP
访问public init(String[] credentials) {
Account account = null;
String uniqueID = uniqueAccountIdentifier(credentials);
synchronized (SHARED_ACCOUNT_HASHMAP) {
if (SHARED_ACCOUNT_HASHMAP.containsKey(uniqueID)) {
account = SHARED_ACCOUNT_HASHMAP.get(uniqueID);
log("...retrieved Shared Account object: %s", uniqueID);
}
// create the Account object (if necessary)
if (account == null) {
account = new Account(credentials);
// Store it in the SHARED_ACCOUNT_HASHMAP
SHARED_ACCOUNT_HASHMAP.put(uniqueID, account);
log("...created Account object: %s",uniqueID);
}
}
}
:
{{1}}
答案 1 :(得分:1)
如果您有多个读者/作者,请考虑使用ReadWriteLock(参见ReadWriteLock example)。
通常,ConcurrentHashMap的性能优于您正在使用的同步哈希映射。
答案 2 :(得分:1)
在以下代码中,当您尝试在同步地图(check-then-act
和containsKey
)上执行两项操作时,我会感觉到种族条件get
的气味:
if (SHARED_ACCOUNT_HASHMAP.containsKey(uniqueID)) {
account = SHARED_ACCOUNT_HASHMAP.get(uniqueID);
log("...retrieved Shared Account object: %s", uniqueID);
}
因此,为了避免竞争条件,您需要在此地图上进行同步:
synchronized (synchronizedMap) {
if (SHARED_ACCOUNT_HASHMAP.containsKey(uniqueID)) {
account = SHARED_ACCOUNT_HASHMAP.get(uniqueID);
log("...retrieved Shared Account object: %s", uniqueID);
}
// rest of the code.
}
实际上synchronizedMap
可以保护自己免受可能破坏地图数据的内部竞争条件的影响,但是对于外部条件(如上所述),您需要注意这一点。如果您觉得在许多地方使用synchronized
块,您还可以考虑使用常规地图和同步块。你会发现这个question也很有用。