Java 是否有理由使用同步集合初始化实体属性?

Java 是否有理由使用同步集合初始化实体属性?,java,jpa,eclipselink,Java,Jpa,Eclipselink,对于我工作的项目中的JPA实体,List或Map类型的属性总是初始化为synchronized Implementation Vector和Hashtable。 (非同步ArrayList和HashMap是Java中的标准实现,除非确实需要同步。) 有人知道为什么需要同步收集吗?我们使用日食 当我问起这件事时,没有人知道为什么会这样做。好像一直都是这样。也许这是旧版本的EclipseLink所需要的 我提出这个问题有两个原因: 我更喜欢像其他地方一样使用标准实现ArrayList和Hash

对于我工作的项目中的JPA实体,List或Map类型的属性总是初始化为synchronized Implementation Vector和Hashtable。
(非同步ArrayList和HashMap是Java中的标准实现,除非确实需要同步。)

有人知道为什么需要同步收集吗?我们使用日食


当我问起这件事时,没有人知道为什么会这样做。好像一直都是这样。也许这是旧版本的EclipseLink所需要的


我提出这个问题有两个原因:

  • 我更喜欢像其他地方一样使用标准实现ArrayList和HashMap。如果安全的话
  • JDK中没有匹配的同步集实现。至少不像EclipseLink所期望的那样是可序列化的
示例实体:

@Entity
public class Person {
    ...

    @ManyToMany(cascade=CascadeType.ALL)
    @JoinTable( ... )
    private List<Role> accessRoles;


    @ElementCollection
    @CollectionTable( ... )
    @MapKeyColumn(name="KEY")
    @Column(name="VALUE")
    private Map<String, String> attrs;

    public Person() {
        // Why Vector/Hashtable instead of ArrayList/HashMap?
        accessRoles = new Vector<Role>();
        attrs = new Hashtable<String, String>();
    }

    public List<Role> getAccessRoles() {
        return accessRoles;
    }

    public void setAccessRoles(List<Role> accessRoles) {
        this.accessRoles = accessRoles;
    }

    public Map<String, String> getAttrs() {
        return attrs;
    }

    public void setAttrs(Map<String, String> attrs) {
        this.attrs = attrs;
    }
}
@实体
公共阶层人士{
...
@多个(级联=级联类型.ALL)
@可接合(…)
私有列表访问角色;
@元素集合
@收集表(…)
@MapKeyColumn(name=“KEY”)
@列(name=“VALUE”)
私有地图属性;
公众人士(){
//为什么矢量/哈希表而不是ArrayList/HashMap?
accessRoles=新向量();
attrs=新哈希表();
}
公共列表getAccessRoles(){
返回访问角色;
}
public void setAccessRoles(列出accessRoles){
this.accessRoles=accessRoles;
}
公共地图getAttrs(){
返回属性;
}
公共无效设置属性(映射属性){
this.attrs=attrs;
}
}

JPA不需要同步集合,它应该只与业务逻辑相关。。我想它不需要这个。。因为你会知道的


因此,基本上建议使用“不同步”,这将提高性能。

JPA不需要同步集合,它应该只与业务逻辑相关。。我想它不需要这个。。因为你会知道的


因此,基本上建议使用“不同步”,这样可以提高性能。

通常不需要向量,更常用的是ArrayList。因此,如果您当前的代码库中充满了向量,这就有点代码味道,确保您的团队成员知道它们之间的区别是明智的。另见和

这并不意味着您应该进行大清理,并用ArrayList替换现有代码中的所有向量

  • 您的代码使用列表,编程时不会注意到任何差异
  • 预期的唯一优势是性能提高
  • 很难判断您的代码是否都不依赖于向量提供的同步
因此,除非您当前遇到性能问题,或者正在明确(重新)设计整个代码库的同步,否则您可能会引入难以修复的并发错误,而没有任何好处

另外,请注意,当多个线程同时访问您的集合时,向量的使用对性能影响最大。因此,如果您正遭受性能损失,并因此决定替换向量,则需要非常小心以保持访问充分同步


编辑:您专门询问EclipselinkJPA

如果他们要求您使用向量和哈希表,那将相当令人惊讶,因为这意味着他们要求您依赖过时的数据结构。 在中,他们使用ArrayList和HashMaps,因此我们可以得出结论,事实并非如此

深入到源代码中,我们可以看到他们使用集合接口,而不关心集合的实现。然而,当您的内部集合类是Vector时,它确实有一些特殊情况。例如,见。它是向量,尽管你可以改变它

另见

EclipseLink和您的列表相遇的最具侵扰性的时刻是您懒散地加载集合的时候。EclipseLink将用自己的间接列表替换集合,间接列表内部使用向量。在这些情况下,EclipseLink将以任何方式为您提供一个向量(!),您在集合的初始化中指定的集合甚至都无关紧要

所以EclipseLink确实更喜欢使用向量和 带EclipseLink的向量意味着更少的对象引用从 从一个集合到另一个集合


通常不需要向量,更常用的是ArrayList。因此,如果您当前的代码库中充满了向量,这就有点代码味道,确保您的团队成员知道它们之间的区别是明智的。另见和

这并不意味着您应该进行大清理,并用ArrayList替换现有代码中的所有向量

  • 您的代码使用列表,编程时不会注意到任何差异
  • 预期的唯一优势是性能提高
  • 很难判断您的代码是否都不依赖于向量提供的同步
因此,除非您当前遇到性能问题,或者正在明确(重新)设计整个代码库的同步,否则您可能会引入难以修复的并发错误,而没有任何好处

另外,请注意,当多个线程同时访问您的集合时,向量的使用对性能影响最大。因此,如果您正遭受性能损失,并因此决定替换向量,则需要非常小心以保持访问充分同步


编辑:您专门询问EclipselinkJPA

如果他们要求您使用向量和哈希表,那将相当令人惊讶,因为这将意味着他们要求您重新定义
IndirectList.java
..........................
.........................

/**
     * INTERNAL:
     * Return the valueHolder.
     * This method used to be synchronized, which caused deadlock.
     */
    public ValueHolderInterface getValueHolder() {
        // PERF: lazy initialize value holder and vector as are normally set after creation.
        if (valueHolder == null) {
            synchronized(this) {
                if (valueHolder == null) {
                        valueHolder = new ValueHolder(new Vector(this.initialCapacity, this.capacityIncrement));
                }
            }
        }
        return valueHolder;
    }

...................
..................