问题现象

我们从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. IoC容器-Bean管理XML方式(注入内部bean和级联赋值)

    注入属性-内部bean和级联赋值 (1)一对多关系:部分和员工 一个部门有多个员工,一个员工属于一个部门 部门是一,员工是多 (2)在实体类之间表示一对多关系 (3)在spring配置文件中进行配置 ...

  2. JavaScript之详述闭包导致的内存泄露

    一.内存泄露 1. 定义:一块被分配的内存既不能使用,也不能回收.从而影响性能,甚至导致程序崩溃. 2. 起因:JavaScript的垃圾自动回收机制会按一定的策略找出那些不再继续使用的变量,释放其占 ...

  3. 009 Linux 文件大小统计与排序( du于df和sort)

    @ 目录 01 du 与 df 作用与区别? du(disk usage) df(disk free) 02 du 常用命令示例 03 sort 常用参数 04 常用组合 du + sort + he ...

  4. Mac iterm2 配色以及终端大小写敏感解决方案

    iterm2是mac下非常好用的一款终端.但默认的配色实在不好用,经过一翻搜索终于找到了比较满意的,以下贴出博主的解决方案 配色 首先修改 ~/.bash_profile 加入一下代码 #enable ...

  5. Hive安装教程

    Hive的安装和使用 我的版本: JAVA_HOME=/usr/local/soft/jdk1.8.0_171 HADOOP_HOME=/usr/local/soft/hadoop-2.7.6 HIV ...

  6. Sleep_Yield_Join

    名称解释 Sleep:意思就是睡眠,当前线程暂停一段时间让给别的线程去运行;Sleep是怎么复活的?由你的睡眠时间而定,等睡眠到规定的时间自动复活. Yield:就是当前线程正在执行的时候停止下来进入 ...

  7. GC基础知识

    内存溢出和内存泄漏 内存溢出(Out Of Memory) 就是申请内存时,JVM没有足够的内存空间.通俗说法就是去蹲坑发现坑位满了. 内存泄露 (Memory Leak) 就是申请了内存,但是没有释 ...

  8. iptables简单使用

    1.安装iptables yum install iptables-services 2.iptables简单使用 iptables防火墙文件路径/etc/sysconfig/iptables sys ...

  9. libcurl库openssl编译

    openssl编译 win32: perl Configure  no-shared VC-WIN32 --prefix=E:/lib/openssl-1.1.1 linux: ./config -f ...

  10. Jackson转换为Collection、Array

    1. Jackson转化为Array 注意的地方就是实体类一定要有无参的构造方法,否则会报异常 //com.fasterxml.jackson.databind.exc.InvalidDefiniti ...