【发布时间】:2017-07-28 14:09:50
【问题描述】:
您如何看待,我们是否需要使用同步块来更好地优化对 Ad 实例的访问? Ad.class 的实例可以从不同的线程中检索。同步有助于通过 ConcurrentHashMap 的一次获取操作一次获取一个实例。 ConcurrentHashMap 将所有值存储为 volatile。我在 java 1.7 for android 上使用它,computeIfAbsent 在 java 1.8 中可用。
很高兴得到详细的答案,为什么不或为什么是。 谢谢!
public final class Ad {
private final static Map<String, Ad> ads = new ConcurrentHashMap<>();
public static Ad get(@NonNull String appId) {
if (appId == null) appId = "";
boolean containsAd = ads.containsKey(appId);
Ad localInstance = containsAd ? ads.get(appId) : null;
if (localInstance == null) {
synchronized (Ad.class) {
containsAd = ads.containsKey(appId);
localInstance = containsAd ? ads.get(appId) : null;
if (localInstance == null) {
localInstance = new Ad();
localInstance.setAdId(appId);
ads.put(appId, localInstance);
}
}
}
return localInstance;
}
private Ad() {
}
}
更新:感谢大家的帮助。我将 ConcurrentHashMap 替换为 HashMap。
【问题讨论】:
-
如果你阅读了javadocs,这个类被设计用来防止锁定。同步块没有意义。您不妨使用哈希表
-
是的,如果您发现自己同时使用了
synchronized和ConcurrentHashMap,那么您要么没有正确使用ConcurrentHashMap,要么您应该使用非线程安全的集合。
标签: java android multithreading volatile concurrenthashmap