在ehcache中放置一个元素时出现以下错误。有谁知道为什么会出现这个错误?
提前谢谢。
这是放方法:
@SuppressWarnings("unchecked")
@Override
public void putActivity(Activity activity) {
// put activity itself
Serializable activityKey = KEY_PREFIX_ACTIVITY + activity.getId();
final Element activityElement = new Element(activityKey, activity);
getCache().put(activityElement);
// add activity to the list of user
ArrayList<Activity> activities = null;
Serializable userKey = KEY_PREFIX_USER_ACTIVITIES + activity.getExecutingUserId();
Element userActivities = getCache().get(userKey);
if (userActivities == null) {
activities = new ArrayList<Activity>();
userActivities = new Element(userKey, activities);
} else {
activities = (ArrayList<Activity>) userActivities.getObjectValue();
}
activities.add(activity);
getCache().put(userActivities);
}
这是相应的erorr:
Mrz 05, 2016 11:07:40 AM net.sf.ehcache.store.disk.DiskStorageFactory$DiskWriteTask call
Schwerwiegend: Disk Write of u-1 failed:
net.sf.ehcache.CacheException: Failed to serialize element due to ConcurrentModificationException. This is frequently the result of inappropriately sharing thread unsafe object (eg. ArrayList, HashMap, etc) between threads
at net.sf.ehcache.store.disk.DiskStorageFactory.serializeElement(DiskStorageFactory.java:405)
at net.sf.ehcache.store.disk.DiskStorageFactory.write(DiskStorageFactory.java:385)
at net.sf.ehcache.store.disk.DiskStorageFactory$DiskWriteTask.call(DiskStorageFactory.java:477)
at net.sf.ehcache.store.disk.DiskStorageFactory$PersistentDiskWriteTask.call(DiskStorageFactory.java:1071)
at net.sf.ehcache.store.disk.DiskStorageFactory$PersistentDiskWriteTask.call(DiskStorageFactory.java:1055)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.util.ConcurrentModificationException
at java.util.ArrayList.writeObject(Unknown Source)
at sun.reflect.GeneratedMethodAccessor33.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at java.io.ObjectStreamClass.invokeWriteObject(Unknown Source)
at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.defaultWriteFields(Unknown Source)
at java.io.ObjectOutputStream.defaultWriteObject(Unknown Source)
at net.sf.ehcache.Element.writeObject(Element.java:875)
at sun.reflect.GeneratedMethodAccessor31.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at java.io.ObjectStreamClass.invokeWriteObject(Unknown Source)
at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.writeObject(Unknown Source)
at net.sf.ehcache.util.MemoryEfficientByteArrayOutputStream.serialize(MemoryEfficientByteArrayOutputStream.java:97)
at net.sf.ehcache.store.disk.DiskStorageFactory.serializeElement(DiskStorageFactory.java:403)
... 10 more
以及来自ehcache源代码的更多详细信息:
private MemoryEfficientByteArrayOutputStream [More ...] serializeElement(Element element) throws IOException {
// A ConcurrentModificationException can occur because Java's serialization
// mechanism is not threadsafe and POJOs are seldom implemented in a threadsafe way.
// e.g. we are serializing an ArrayList field while another thread somewhere in the application is appending to it.
try {
return MemoryEfficientByteArrayOutputStream.serialize(element);
} catch (ConcurrentModificationException e) {
throw new CacheException("Failed to serialize element due to ConcurrentModificationException. " +
"This is frequently the result of inappropriately sharing thread unsafe object " +
"(eg. ArrayList, HashMap, etc) between threads", e);
}
}
答案 0 :(得分:3)
您正在序列化对象时更新对象(ehcache尝试将其保存到磁盘)。您应该只在缓存中存储一个不可变对象。
在您的情况下,不要尝试重用ArrayList,创建一个新的:
if (userActivities == null) {
activities = new ArrayList<Activity>();
userActivities = new Element(userKey, activities);
} else {
activities = new ArrayList<Activity>((List) userActivities.getObjectValue());
}
答案 1 :(得分:0)
您可以实例化 CopyOnWriteArrayList,而不是 ArrayList。