【发布时间】:2014-10-10 19:46:19
【问题描述】:
在 Effective Java 第 2 章第 1 项中,Bloch 建议考虑静态工厂方法而不是构造函数来初始化对象。他提到的好处之一是这种模式允许类从重复调用中返回相同的对象:
静态工厂方法从重复调用返回相同对象的能力允许类在任何时候保持对存在的实例的严格控制。执行此操作的类被称为实例控制。编写实例控制类有几个原因。实例控制允许一个类保证它是单例(第 3 项)或不可实例化(第 4 项)。此外,它允许不可变类(第 15 条)保证不存在两个相等的实例:a.equals(b) 当且仅当 a==b。
这种模式在多线程环境中如何工作?例如,我有一个不可变的类,它应该是实例控制的,因为一次只能存在一个具有给定 ID 的实体:
public class Entity {
private final UUID entityId;
private static final Map<UUID, Entity> entities = new HashMap<UUID, Entity>();
private Entity(UUID entityId) {
this.entityId = entityId;
}
public static Entity newInstance(UUID entityId) {
Entity entity = entities.get(entityId);
if (entity == null) {
entity = new Entity(entityId);
entities.put(entityId, entity);
}
return entity;
}
}
如果我从分离的线程中调用newInstance() 会发生什么?我怎样才能使这个类线程安全?
【问题讨论】:
-
不要忘记,如果实体不再从内部映射中删除,这可能会导致内存泄漏!根据您的用例,也可能需要销毁实体!
-
@isnot2bad 更好的是,保留
WeakReferences,它仍然保证每个guid 最多存在1 个实时Entity实例,但垃圾收集很快。
标签: java multithreading multiton