Caffeine缓存注意事项(避坑)-引用的都是同一地址的数据

Caffeine缓存注意事项-引用的都是同一地址的数据

Caffeine使用大家可以网上自行搜索,在这我就不在说明如何使用Caffeine了.

文章中心描述就是获取缓存中同一数据,如果对该数据某些字段参数赋值/改变会影响该缓存数据,全部代码在文末.

1: Caffeine中放入缓存数据(keyId1,keyId2,keyId3,keyId4)

public static void main(String[] args) {
    
    
        for (int i = 0; i < 5; i++) {
    
    
            String key = "keyId" + i;
            int id = 10 + i;
            int age = 10 + i;
            String name = "test" + i;
            //查询缓存,未命中赋值放入缓存(如:如果cache不存在,查询数据库,这里直接声明对象赋值)
            CacheVo res = (CacheVo)cacheCaffeine.get(key, cacheVo -> {
    
    
                CacheVo build = CacheVo.builder().id(id).age(age).name(name).build();
                return build;
            });
        }
        ArrayList<CacheVo> cacheVos = new ArrayList<>();
        String key1 = "keyId1";
        String key2 = "keyId2";
        String key3 = "keyId3";
        CacheVo ifPresent1 = (CacheVo)cacheCaffeine.getIfPresent(key1);
        ifPresent1.setRefId(1);
        cacheVos.add(ifPresent1);
        CacheVo ifPresent2 = (CacheVo)cacheCaffeine.getIfPresent(key2);
        ifPresent2.setRefId(2);
        cacheVos.add(ifPresent2);
        CacheVo ifPresent3 = (CacheVo)cacheCaffeine.getIfPresent(key3);
        ifPresent3.setRefId(3);
        cacheVos.add(ifPresent3);
        // 下面获取相同key 缓存(获取keyId1缓存)
        CacheVo ifPresent4 = (CacheVo)cacheCaffeine.getIfPresent(key1);
        ifPresent4.setRefId(4);
        cacheVos.add(ifPresent4);
        CacheVo ifPresent5 = (CacheVo)cacheCaffeine.getIfPresent(key1);
        ifPresent5.setRefId(5);
        cacheVos.add(ifPresent5);
    }

2:debug查看集合中已放入的缓存对象数据,如下图,此时cacheVos集合中放入的是key为keyId1,keyId2,keyId3的数据(当前未插入相同key数据,so此时看似一切正常,注意集合前3个对象地址值和refId值)
图1
3:cacheVos再次插入key为keyId1的数据,RefId赋值为4.如下图:细心的读者会发现cacheVos中index为0和3的数据是相同地址,且cacheVos中index为0的VO中refId值也变为4了.
在这里插入图片描述
此时再次debug获取key为keyId1的数据,读者会发现内存中的数据已改变.redId属性初始时并不是4
在这里插入图片描述
4:cacheVos再次插入key为keyId1的数据,RefId赋值为5.如下图:读者会发现cacheVos中index为0,3和4的数据是相同地址,且cacheVos中index为0的VO中refId值也变为5了.此时内存中的refId值也变为5
在这里插入图片描述
5:内存中key为keyId1的数据属性也已变化(多次都是对同一地址的VO对象改变refId属性值)
在这里插入图片描述
总结: Caffeine缓存中获取相同key的数据都是相同对象(地址相同),对该对象数据进行操作时会相应的改变内存缓存中的属性!!!大家注意使用避坑. 欢迎大家指点,第一次写博客,多多指教,有不足之处,请指出,谢谢.

所有test代码:

import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import lombok.Builder;
import lombok.Data;

import java.util.ArrayList;
import java.util.concurrent.TimeUnit;

/**
 * @description: Caffeine缓存注意事项-引用的都是同一地址的数据
 * @author: GL
 * @create: 2021-11-03 16:39
 **/
public class CaffeineTest {
    
    
    /**
     *       maximumSize: 缓存的最大数量
     *     - maximumWeight: 缓存的最大权重
     *     - expireAfterAccess: 最后一次读或写操作后经过指定时间过期
     *     - expireAfterWrite: 最后一次写操作后经过指定时间过期
     *     - refreshAfterWrite: 创建缓存或者最近一次更新缓存后经过指定时间间隔,刷新缓存
     *     expireAfterWrite和expireAfterAccess同时存在时,以expireAfterWrite为准
     */
    private static Cache<String, Object> cacheCaffeine = Caffeine.newBuilder()
            .expireAfterWrite(24, TimeUnit.HOURS) //写入后隔段时间过期
            // .refreshAfterWrite(60, TimeUnit.MINUTES) //写入后隔段时间刷新
            // .expireAfterAccess(10, TimeUnit.HOURS) //访问后隔段时间过期
            .maximumSize(1000)//最大条数
            .build();//定义cache

    public static void main(String[] args) {
    
    
        for (int i = 0; i < 5; i++) {
    
    
            String key = "keyId" + i;
            int id = 10 + i;
            int age = 10 + i;
            String name = "test" + i;
            //查询缓存,未命中赋值放入缓存(如:如果cache不存在,查询数据库,这里直接声明对象赋值)
            CacheVo res = (CacheVo)cacheCaffeine.get(key, cacheVo -> {
    
    
                CacheVo build = CacheVo.builder().id(id).age(age).name(name).build();
                return build;
            });
        }
        ArrayList<CacheVo> cacheVos = new ArrayList<>();
        String key1 = "keyId1";
        String key2 = "keyId2";
        String key3 = "keyId3";
        CacheVo ifPresent1 = (CacheVo)cacheCaffeine.getIfPresent(key1);
        ifPresent1.setRefId(1);
        cacheVos.add(ifPresent1);
        CacheVo ifPresent2 = (CacheVo)cacheCaffeine.getIfPresent(key2);
        ifPresent2.setRefId(2);
        cacheVos.add(ifPresent2);
        CacheVo ifPresent3 = (CacheVo)cacheCaffeine.getIfPresent(key3);
        ifPresent3.setRefId(3);
        cacheVos.add(ifPresent3);
        // 下面获取相同key 缓存(获取keyId1缓存)
        CacheVo ifPresent4 = (CacheVo)cacheCaffeine.getIfPresent(key1);
        ifPresent4.setRefId(4);
        cacheVos.add(ifPresent4);
        CacheVo ifPresent5 = (CacheVo)cacheCaffeine.getIfPresent(key1);
        ifPresent5.setRefId(5);
        cacheVos.add(ifPresent5);
    }
}
@Data
@Builder
class CacheVo{
    
    
    private Integer id;
    private Integer age;
    private String name;
    private Integer refId;
}

猜你喜欢

转载自blog.csdn.net/qq_31686241/article/details/121124595
今日推荐