【发布时间】:2017-02-23 08:00:05
【问题描述】:
我有这个单身人士。正如我所做的enum 一样,它对于getInstance 是线程安全的。
public enum ExtensionRegistry {
REGISTRY;
private static final Logger LOGGER = LoggerFactory.getLogger(ExtensionRegistry.class);
// key is a class name
private Map<String, Plugin> extensions = new HashMap<>();
public void registerPlugin(Plugin plugin) {
LOGGER.info("Register plugin: [{}].", plugin);
extensions.put(plugin.getId(), plugin);
}
public Plugin getPlugin(String id) {
return extensions.get(id);
}
public List<String> listAvailablePlugins() {
return extensions.values().stream()
.map(Plugin::getId)
.collect(Collectors.toList());
}
public IPluggable getRegisteredClass(String id) {
Plugin plugin = extensions.get(id);
if (null == plugin) {
LOGGER.debug("No class with id [{}] found in the registry!", id);
return null;
} else {
IPluggable instance = null;
try {
instance = (IPluggable) Class.forName(plugin.getId()).newInstance(); // should exist!
} catch (Exception exc) {
LOGGER.error("Failed to create instance of class with id [{]].", id, exc);
}
return instance;
}
}
}
为了使其真正线程安全,我还应该更改/同步哪些内容?使用ConcurrentHashMap?为每个方法添加synchronized?
【问题讨论】:
-
同步公共方法。
HashMap不是线程安全的;您需要在所有这些方法中独占访问它。 -
@AndyTurner 但如果我做到了
ConcurrentHashMap它不会有帮助吗?因为例如registerPlugin方法使其同步没有意义,因为它只有一个动作 -
动作的数量无关紧要。执行该操作的线程数是相关的。不同步,没有锁,缺乏并发结构,那些对
plugin的多次访问和返回它的方法注定要在并发上下文中。 -
那我什么时候需要
ConcurrentHashMap?因为据我了解,我可以将HashMap留在那里 -
绝不允许两个线程同时写入同一个 HashMap,绝不允许线程写入而另一个线程读取 HashMap。如果这两种情况中的任何一种都可能发生,请使用 ConcurrentHashMap
标签: java concurrency synchronized concurrenthashmap