Caffeine caching precautions (avoiding pitfalls) - all refer to data at the same address

Caffeine caching precautions - all refer to data at the same address

You can search for Caffeine on the Internet. I will not explain how to use Caffeine here.

The central description of the article is to obtain the same data in the cache. If certain field parameters of the data are assigned/changed, it will affect the cached data. All codes are at the end of the article.

1: Put cache data (keyId1, keyId2, keyId3, keyId4) into Caffeine

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 to view the cache object data that has been placed in the collection, as shown below. At this time, the cacheVos collection contains data with keys keyId1, keyId2, and keyId3 (the same key data is not currently inserted, so everything seems to be normal at this time) , pay attention to the collection of the first three object address values ​​​​and refId values)
figure 1
3: cacheVos inserts the data with key keyId1 again, and RefId is assigned a value of 4. As shown below: Careful readers will find that the data with index 0 and 3 in cacheVos are the same address. And the refId value in the VO with index 0 in cacheVos has also changed to 4.
Insert image description here
At this time, debug again to obtain the data with key keyId1. Readers will find that the data in the memory has changed. The redId attribute was not 4 initially. 4
Insert image description here
: cacheVos is inserted again The key is the data of keyId1, and the RefId is assigned a value of 5. As shown below: readers will find that the data with index 0, 3 and 4 in cacheVos are at the same address, and the refId value in the VO with index 0 in cacheVos has also changed to 5. This The refId value in the memory also changes to 5.
Insert image description here
5: The data attribute with the key keyId1 in the memory has also changed (the refId attribute value has been changed for the VO object at the same address many times). Summary
Insert image description here
: The data with the same key is obtained from the Caffeine cache. It is the same object (same address). When operating on the object data, the attributes in the memory cache will be changed accordingly!!! Please pay attention to avoid pitfalls. Welcome everyone to give advice. It is my first time to write a blog. Please give me some advice. If there are any shortcomings, , please point it out, thank you.

All test codes:

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

Guess you like

Origin blog.csdn.net/qq_31686241/article/details/121124595