ehcache使用报错

更改缓存后,线上日志报了一个缓存错误
[ERROR]-[Thread: five%004dinute.data]-[net.sf.ehcache.store.disk.DiskStorageFactory$DiskWriteTask.call()]: Disk Write of get-goods-byUuid-0d695dbae6574a19963c412e19c6cc8d 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(FutureTask.java:262)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:178)

代码如下:

String goodsCacheKey = PropKit.get("SYSTEMID")+"get-goods-byUuid-"+uuid;
Goods goods = CacheKit.get("fiveMinute", goodsCacheKey);
if (goods == null) {
    goods = srv.getIsSaleGoodByUuid(uuid, pid);
    CacheKit.put("fiveMinute", goodsCacheKey, goods);
}

调查后发现说是可能内存数据被多次修改的问题,需要重新new新的出来,我想问下波总,我看了下最新文档,使用上也没有提需要这样的操作,如果真是这个问题的话jfinal直接在返回的时候实现下是不是更好?

注:jfinal版本是3.3

评论区

JFinal

2019-04-24 11:33

这个是因为你的某个 ArrayList HashMap 对象在存入 ehcache 之前迭代序列化时,另一个线程对这个 list、map 进行了修改操作

JFinal

2019-04-24 11:35

这么来理解:
1:ehcache 正在对你的 list 进行类似下面的动作:
for ( Type x : list) {
...
}

2:你的另一个线程也在对上面的 list 进行操作,但是在进行写操作
list.add(...);

这本质还是一个 Java 基础问题: ArrayList 、HashMap 这类容器在迭代的过程中,另一个线程只能读不能写

热门反馈

扫码入社