ConcurrentModificationException和一个HashMap
我正在使用JPA持久对象。 主对象与另一个对象拥有一对多的关系。 另一个对象存储在一个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)
这不是同步问题。 如果正在迭代的底层集合被Iterator本身以外的其他任何东西修改,就会发生这种情况。
Iterator it = map.entrySet().iterator(); while (it.hasNext()) { Entry item = it.next(); map.remove(item.getKey()); }
这会在第二次调用it.hasNext()时抛出一个ConcurrentModificationExceptionexception。
正确的做法是
Iterator it = map.entrySet().iterator(); while (it.hasNext()) { Entry item = it.next(); it.remove(); }
假设这个迭代器支持remove()操作。
尝试使用ConcurrentHashMap而不是普通的HashMap
这听起来不像Java同步问题,更像是数据库locking问题。
我不知道是否向所有持久化类添加一个版本会将其sorting,但这是Hibernate可以独占访问表中的行的一种方式。
可能是隔离级别需要更高。 如果你允许“脏读”,也许你需要碰到序列化。
尝试CopyOnWriteArrayList或CopyOnWriteArraySet取决于你正在尝试做什么。