问题

我正在使用JPA持久化对象。 Main对象与另一个对象拥有一对多的关系。另一个对象存储在HashMap中。什么样的同步可以解决这个问题?它似乎发生在完全随机的时间,并且非常难以预测。这是我得到的例外:

Exception in thread "pool-1-thread-1" java.util.ConcurrentModificationException
        at java.util.HashMap$HashIterator.nextEntry(Unknown Source)
        at java.util.HashMap$ValueIterator.next(Unknown Source)
        at org.hibernate.collection.AbstractPersistentCollection$IteratorProxy.next(AbstractPersistentCollection.java:555)
        at org.hibernate.engine.Cascade.cascadeCollectionElements(Cascade.java:296)
        at org.hibernate.engine.Cascade.cascadeCollection(Cascade.java:242)
        at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:219)
        at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:169)
        at org.hibernate.engine.Cascade.cascade(Cascade.java:130)

#1 热门回答(220 赞)

这不是同步问题。如果正在迭代的基础集合被Iterator本身以外的任何东西修改,则会发生这种情况。

Iterator it = map.entrySet().iterator();
while (it.hasNext())
{
   Entry item = it.next();
   map.remove(item.getKey());
}

当第二次调用it.hasNext()时,这将抛出ConcurrentModificationException。

正确的做法是

Iterator it = map.entrySet().iterator();
   while (it.hasNext())
   {
      Entry item = it.next();
      it.remove();
   }

假设这个迭代器支持remove()操作。


#2 热门回答(53 赞)

尝试使用ConcurrentHashMap而不是普通的HashMap


#3 热门回答(3 赞)

它听起来不像Java同步问题,更像是数据库锁定问题。

我不知道在所有持久化类中添加一个版本是否会将其排序,但这是Hibernate可以提供对表中行的独占访问的一种方式。

可能是隔离级别需要更高。如果你允许"脏读",也许你需要提升到可序列化。


原文链接