问题现象

我们从Ehcache中取出缓存的对象,之后将对象中的属性进行了修改使用。等再次从缓存中拿到对象后,发现对象的值变成了上一次调用修改后的对象了。

原因

Ehcache中缓存的是原对象的引用,所以引用的内容被修改后cache内部的值也会被修改。

解决方案

使用Ehcache的copyStrategy

Ehcache提供了copyOnRead="true" copyOnWrite="true"的配置属性。

作用是在读取或写入数据时,不使用原始数据,而是使用拷贝数据。

但是在使用该配置的时候,还要提供copyStrategy class属性,提供Copy策略。

<cache name="bannerCache" eternal="false" maxElementsInMemory="50"
overflowToDisk="false" diskPersistent="false" timeToIdleSeconds="300"
timeToLiveSeconds="300" memoryStoreEvictionPolicy="LFU" copyOnRead="true" copyOnWrite="true">
<copyStrategy class="com.xxx.EhcacheCopyStrategy" />
</cache>

copy策略类

public class EhcacheCopyStrategy implements ReadWriteCopyStrategy<Element> {
@Override
public Element copyForWrite(Element value) {
if(value != null){
Object temp=(Serializable)value.getObjectValue();
try {
return new Element(value.getObjectKey(),deepCopy(temp));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return value;
}
@Override
public Element copyForRead(Element storedValue) {
if(storedValue != null){
Object temp=(Serializable)storedValue.getObjectValue();
try {
return new Element(storedValue.getObjectKey(),deepCopy(temp));
} catch (ClassNotFoundException | IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return storedValue;
} private Object deepCopy(Object src) throws IOException, ClassNotFoundException {
ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(byteOut);
out.writeObject(src); ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());
ObjectInputStream in = new ObjectInputStream(byteIn);
return in.readObject();
}
}

使用immutable对象

将我们的实体类设计成immutable的,如果需要修改就创建一个新的对象。

如何构建一个immutable对象

  • 确保fields中的成员都被private final修饰;private保证内部成员不会被外部直接访问,final保证成员在初始化后不会被assigned。
  • 不提供改变成员的方法,例如setXxx。
  • 使用final修饰自定义的类,确保类中的方法不会被重写。
  • 如果类中的某个成员是mutable类型的,那么在初始化该成员或者企图用get方法从外部对其观察时,应该使用深度拷贝,确保immutable。

String类

String类是java中典型的immutable数据类型,一个String对象一旦呗new出来后,就不能被修改,否则就会报assigned错误。

StringBuilder类的对象是mutable的数据类型,当一个StringBuilder对象被创建出来之后,其内部的值是可以通过某些内部方法进行改变的。

修改Ehcache缓存中取到的值,缓存中的值也被修改了的更多相关文章

  1. 多线程查询数据,将结果存入到redis中,最后批量从redis中取数据批量插入数据库中【我】

    多线程查询数据,将结果存入到redis中,最后批量从redis中取数据批量插入数据库中 package com.xxx.xx.reve.service; import java.util.ArrayL ...

  2. 【算法与数据结构】在n个数中取第k大的数(基础篇)

    (转载请注明出处:http://blog.csdn.net/buptgshengod) 题目介绍            在n个数中取第k大的数(基础篇),之所以叫基础篇是因为还有很多更高级的算法,这些 ...

  3. Mybatis的二级缓存、使用Redis做二级缓存

    目录 什么是二级缓存? 1. 开启二级缓存 如何使用二级缓存: userCache和flushCache 2. 使用Redis实现二级缓存 如何使用 3. Redis二级缓存源码分析 什么是二级缓存? ...

  4. hibernate的二级缓存----collection和query的二级缓存

    collection二级缓存: 不使用集合的二级缓存时: 运行下面的代码: @Test public void testCollectionSecondLevelCache1(){ Departmen ...

  5. SpringBoot学习笔记(10)-----SpringBoot中使用Redis/Mongodb和缓存Ehcache缓存和redis缓存

    1. 使用Redis 在使用redis之前,首先要保证安装或有redis的服务器,接下就是引入redis依赖. pom.xml文件如下 <dependency> <groupId&g ...

  6. react+dva 全局model中异步获取数据state在组件中取不到值

    先上结论,不是取不到,是写法有问题. 全文分4部分,1是问题描述,2是一开始的解决想法(错误做法),3是问题产生原因的思考,4是正常解决方法.只想看结论直接跳4 1.问题描述 接触react dva一 ...

  7. ComboboxColumn取值——Winform中DataGridView中某一列使用下拉框

    ComboboxColumn的用法网上很多,绑定数据源都很简单,这里我遇到的是.不绑定数据源,即所有comobox的绑定都是固定的几个数据: 可以看到没有绑定任何数据源, ,在后台cs中取到下拉框的值 ...

  8. DataGrid中取HyperLinkColumn列的值,处理DataGrid中绑定的特殊字符

    DataGrid中取HyperLinkColumn列的值. /// <summary> /// 对datagrid中标签进行编码,处理特殊字符 /// </summary> / ...

  9. action中list传到JSP中取不到值的问题

    今天遇到了这个问题 action中list传到JSP中取不到值 搞了半天是因为我在JSP中取值的的时候 <s:iterator  value="shlist" var=&qu ...

随机推荐

  1. javaObject—toString方法

    1 package face_object; 2 /* 3 * Object:所有类的根类. 4 * Object是不断抽取而来的,具备所有对象都具备的共性内容. 5 * 常用的共性功能: 6 * 7 ...

  2. python -m详解

    温馨提示: 本篇演示环境是Python 3.8 先python --help看下python -m参数的解释: -m mod : run library module as a script (ter ...

  3. plsql 普通游标

    -- ①普通游标:操作步骤 边敲边想 学无止境 /* 游标:指针:内存中的一块数据缓冲区,上下文: 将查询到的结果集缓存起来,便于进行逐行定位处理. 使用完成后要及时关闭: 操作步骤? 1.定义游标 ...

  4. ApacheCN 深度学习译文集 2020.9

    协议:CC BY-NC-SA 4.0 自豪地采用谷歌翻译 不要担心自己的形象,只关心如何实现目标.--<原则>,生活原则 2.3.c 在线阅读 ApacheCN 面试求职交流群 72418 ...

  5. .NET 诞生已20周年,您的 .NET 技能是否还停留在2010 年?

    20年来,我们见证了超过上千万.NET 开发员,当前有600万.NET 开发者正在使用.NET技术构建各类解决方案.今天,IT市场对.NET 开发人员的需求达到了前所未有的程度,特别是在中国,各大公司 ...

  6. 「JOISC 2014 Day1」 历史研究

    「JOISC 2014 Day1」 历史研究 Solution 子任务2 暴力,用\(cnt\)记录每种权值出现次数. 子任务3 这不是一个尺取吗... 然后用multiset维护当前的区间,动态加, ...

  7. Jvm和CPU保证特定情况下不乱序

    简介 CPU为了提高指令执行效率,会在一条指令执行过程中(比去内存读数据(慢100倍)),去同时执行另一条指令,前提是,两条指令没有依赖关系. CPU保证不乱序 MESI--CPU缓存一致性协议(In ...

  8. Nodejs ORM框架Sequelize快速入门

    Nodejs ORM框架Sequelize快速入门 什么是ORM? 简单的讲就是对SQL查询语句的封装,让我们可以用OOP的方式操作数据库,优雅的生成安全.可维护的SQL代码.直观上,是一种Model ...

  9. AI模型运维——GPU性能监控NVML和DCGM

    最近一年负责运维的GPU主机越来越多,发现现有的监控项无法很好的了解GPU的性能和负载情况,研究了下官方文档,在此记录. 一.NVML和DCGM NVML:https://developer.nvid ...

  10. H5架构和原生架构的区别

    1.App的3种开发方式 表面上看,手机App都是同样的东西,就是手机上的应用程序,点击图标就能运行,但是它们的底层技术不一样.按照开发技术,App可以分成三大类.原生应用(简称nativeApp), ...