【问题标题】:Error serializing element in ehcache在 ehcache 中序列化元素时出错
【发布时间】:2016-06-19 09:25:33
【问题描述】:

将元素放入 ehcache 时出现以下错误。有谁知道为什么会发生此错误?

提前谢谢你。

这是put方法:

  @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);
  }

这里是对应的错误:

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);


         }



  }

【问题讨论】:

    标签: java serialization replication ehcache


    【解决方案1】:

    您可以实例化 CopyOnWriteArrayList,而不是 ArrayList。

    【讨论】:

      【解决方案2】:

      您在序列化对象时更新它(ehcache 尝试将其保存到磁盘)。您应该只在缓存中存储不可变对象。

      在你的情况下,不要尝试重用 ArrayList,创建一个新的:

      if (userActivities == null) {
            activities = new ArrayList<Activity>();
            userActivities = new Element(userKey, activities);
      } else {
            activities = new ArrayList<Activity>((List) userActivities.getObjectValue());
      }
      

      【讨论】:

      • 谢谢,你的意思是这样吗?否则 { 活动 = 新的 ArrayList();活动.addAll((ArrayList) userActivities.getObjectValue()); }
      • 是的,我忘记了演员表
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-16
      • 1970-01-01
      • 1970-01-01
      • 2021-01-09
      • 2014-11-01
      相关资源
      最近更新 更多