java - 实例控制类和多线程

标签 java multithreading multiton

Effective Java 第 2 章第 1 项 Bloch 建议考虑使用静态工厂方法而不是构造函数来初始化对象。他提到的一个好处是这种模式允许类从重复调用中返回相同的对象:

The ability of static factory methods to return the same object from repeated invocations allows classes to maintain strict control over what instances exist at any time. Classes that do this are said to be instance-controlled. There are several reasons to write instance-controlled classes. Instance control allows a class to guarantee that it is a singleton (Item 3) or noninstantiable (Item 4). Also, it allows an immutable class (Item 15) to make the guarantee that no two equal instances exist: a.equals(b) if and only if 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() 会发生什么?如何使此类成为线程安全的?

最佳答案

使新实例同步

public static synchronized Entity newInstance(UUID entityId){
     ...
}

这样一个线程进入新的实例方法后,除非第一个线程完成,否则没有其他线程可以调用此方法。基本上发生的事情是第一个线程获得了整个类的锁。在第一个线程持有该类的锁的时间内,没有其他线程可以进入该类的同步静态方法。

关于java - 实例控制类和多线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25354112/

相关文章:

java - 排序优先队列

java - 将点击监听器添加到 Overlay 类

c# - wpf方法启动应用消息循环

java - Java有没有类似于c++的combinable?

java - 如何让我的 JButton 与我的 JFrame 连接?

java - Tomcat 上的 Jersey REST 服务出现 404 错误

c - QEMU 用户模式模拟退出时是否会阻止 pthread_join 阻塞?

java - Java 中的线程安全多线程

objective-c - Objective-C 中的优雅和 'correct' multiton 实现?