1

作者: Teemo_fca4 | 来源:发表于2022-09-22 10:15 被阅读0次
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>

package com.example.springboottest.guava_cache;

import com.google.common.base.MoreObjects;

/***************************************

  • @author:Alex Wang

  • @Date:2017/11/18

  • QQ: 532500648

  • QQ群:463962286
    ***************************************/
    public class Employee
    {
    private final String name;
    private final String dept;
    private final String empID;
    private final byte[] data = new byte[1024 * 1024];

    public Employee(String name, String dept, String empID)
    {
    this.name = name;
    this.dept = dept;
    this.empID = empID;
    }

    public String getName()
    {
    return name;
    }

    public String getDept()
    {
    return dept;
    }

    public String getEmpID()
    {
    return empID;
    }

    @Override
    public String toString()
    {
    return MoreObjects.toStringHelper(this)
    .add("Name", this.getName()).add("Department", getDept())
    .add("EmployeeID", this.getEmpID()).toString();
    }

    @Override
    protected void finalize() throws Throwable
    {
    System.out.println("The name " + getName() + " will be GC.");
    }
    }

package com.example.springboottest.guava_cache;

import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.cache.Weigher;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

public class _1_CacheLoaderBasicTest {

public static void main(String[] args) throws Exception{

// test1();
// test2();
// test3();
// test4();
test5();
}

/**测试软引用在缓存中被过期
 * 需要设置堆内存信息
 * -Xms64M -Xmx64M -XX:+PrintGCDetails
 * @throws Exception
 */
private static void test5() throws Exception{
    LoadingCache<String, Employee> cache = CacheBuilder.newBuilder()
            .expireAfterWrite(200, TimeUnit.SECONDS)
            .softValues()//只能对values 做软引用处理
            .build(createCacheLoader2());
    int i = 0;
    //Employee 内部会有一个1M的数组,所以一个Employee对象 至少占1M空间
    //由于软引用在内存快不足的时候会被回收 所以这里运行结果 可以创建很多对象 不止64个
    //todo 但是考虑到软引用的性能影响 一般我们在在缓存中设置size来限制缓存所占内存的总大小 而不是使用软引用来
    for (; ; )  {
        String key = "Alex" + i;
        cache.put(key, new Employee(key, key, key));

// cache.get(key);
// System.gc();
System.out.println("The Employee [" + (i++) + "] is store into cache.");
TimeUnit.MILLISECONDS.sleep(200);
}
}

//测试弱引用(weakReference) 在缓存中被过期
public static void test4() throws InterruptedException  {
    LoadingCache<String, Employee> cache = CacheBuilder.newBuilder()
            .expireAfterWrite(2, TimeUnit.SECONDS)
            .weakValues()
            .weakKeys()
            .build(createCacheLoader2());
    cache.getUnchecked("Alex");
    cache.getUnchecked("Guava");

    //active method
    //Thread Active design pattern
    System.gc();
    TimeUnit.MILLISECONDS.sleep(100);
    //weak:弱引用 每次gc的时候 都会将其回收, 所以这里从缓存中拿不到数据了
    System.out.println(cache.getIfPresent("Alex"));
}

//测试Write的expire模式下的缓存存活情况
private static void test3() throws Exception {
    LoadingCache<String, Employee> cache = CacheBuilder.newBuilder()
            //expireAfterWrite,write:包括写(write)和更新(update) 不包括读(read)
            .expireAfterWrite(2, TimeUnit.SECONDS)
            .build(createCacheLoader2());

    cache.getUnchecked("Guava");

    TimeUnit.SECONDS.sleep(1);
    Employee guava = cache.getIfPresent("Guava");
    System.out.println(guava);//1s后guava 此时存活
    TimeUnit.MILLISECONDS.sleep(900);
    guava = cache.getIfPresent("Guava");
    System.out.println(guava);//1.90s guava 此时依然存活

    TimeUnit.SECONDS.sleep(1);
    guava = cache.getIfPresent("Guava");
    System.out.println(guava);//2.99s guava 此时不存活
}

//测试Access的expire模式下的缓存存活情况
private static void test2() throws Exception{
    LoadingCache<String, Employee> cache = CacheBuilder.newBuilder()
            //expireAfterAccess,access:包括读(read),写(write),改(update),都会续长缓存的存活期
            .expireAfterAccess(2, TimeUnit.SECONDS)
            .build(createCacheLoader2());
    cache.getUnchecked("Alex");

    TimeUnit.SECONDS.sleep(3);
    Employee alex =  cache.getIfPresent("Alex");//睡眠了 3s 此时缓存获取不到数据
    System.out.println(alex);

    cache.getUnchecked("Guava");

    TimeUnit.SECONDS.sleep(1);
    Employee employee = cache.getIfPresent("Guava");//此时Guava存在
    System.out.println(employee);

    TimeUnit.SECONDS.sleep(1);
    employee = cache.getIfPresent("Guava");//再次获取Guava 依然存在
    System.out.println(employee);

    TimeUnit.SECONDS.sleep(1);
    employee = cache.getIfPresent("Guava");//再次获取Guava 依然存在
    System.out.println(employee);
}

//测试基础用法
public static void test1() throws ExecutionException, InterruptedException {
    //创建一个缓存容器对象 其最大容量是3,容器内元素存放30ms就过期
    LoadingCache<String, Employee> cache = CacheBuilder.newBuilder()
            .maximumSize(3)
            .expireAfterAccess(30, TimeUnit.MILLISECONDS)
            .build(createCacheLoader());
    //#################################### 测试30ms时间过期 ####################################

// System.out.println(cache.get("Alex").getName());
// TimeUnit.MILLISECONDS.sleep(31);
// System.out.println(cache.get("Alex").getName());
//测试到达容量之后 LRU过期
//#################################### 测试到达size之后被LRU过期(过期策略:size) ####################################
// System.out.println(cache.get("Alex").getName());
// System.out.println(cache.get("allen").getName());
// System.out.println(cache.get("tom").getName());
// System.out.println(cache.get("amy").getName());//此时Alex被过期调,再拿Alex的话会从DB中拿
// System.out.println(cache.size());
// System.out.println(cache.get("Alex").getName());
// System.out.println();
//#################################### 测试到达weight之后被LRU过期(过期策略:自定义) ####################################

    //设置一个称重器 称重的方式是:对象的重量weight = name的长度 + empId的长度 + Dept的长度
    Weigher<String, Employee> weigher = (key, employee) ->
            employee.getName().length() + employee.getEmpID().length() + employee.getDept().length();

    //设置缓存重量限制为45
    LoadingCache<String, Employee> cache2 = CacheBuilder.newBuilder()
            .maximumWeight(45)
            .concurrencyLevel(1)
            .weigher(weigher)
            .build(createCacheLoader());

    cache2.get("Gavin");//缓存重量:15
    cache2.get("Kevin");//缓存重量:30
    cache2.get("Allen");//缓存重量:45
    cache2.get("Jason");//重量已经达到45,此时Gavin被过期

    Employee employee = cache2.getIfPresent("Gavin");//此时再去缓存中拿Gavin 是拿不到的
    System.out.println(employee);


    //#################################### LoadingCache 的一些api ####################################

// 从LoadingCache中拿数据,如果拿不到,会去从DB中拿,
// cache.get("aa");
// 与get()方法的区别是这里不需要显式捕获异常
// cache.getUnchecked("aa");
// 从缓存中拿key对应的数据,如果缓存中没有 就返回null,不会去从DB中拿
// cache.getIfPresent("aa");

}


private static  CacheLoader<String, Employee> createCacheLoader() {
    return new CacheLoader<String, Employee>() {
        @Override
        public Employee load(String key) throws Exception {

// 这里要注意:load的时候不能返回空, 那返回空了怎么办?很有可能命中不了
// if (key.equals("aa")) return null;
System.out.println("从数据库中拿数据: " + key);
return new Employee(key, key, key);
}
};
}

private static CacheLoader<String, Employee> createCacheLoader2()  {
    //也可以使用from()来构建缓存
    return CacheLoader.from(key -> new Employee(key, key, key));
}

}

相关文章

  • 1▪1▪1▪1▪1

    今天是国际劳动节,出门看人头,上路遇堵车,处处挤破头,急哭也停不下车。 不如歇了吧 ...

  • 1+1+1…+1=1

    对“一”的理解: 赠人玫瑰,不仅仅是手留余香。 利益他人,实际上也疗愈了自己。 利他、利己,如此往复循环, 最终利...

  • (-1)×(-1)= 1

    数学家经过很长一段时间才认识到(-1)×(-1)= 1是不能被证明的(即使大数学家欧拉曾给出不能令人信服的...

  • 1-2-1-1-1

    【下马请罪】 子龙下马,向张飞跪地请罪道:“张将军,一时失手……”话未停,便被张飞一矛刺了个透心凉。子龙堵着胸口汩...

  • 1 1:1 1(原创小说)

    闪回:那天她…… 当时,我确实听到了那个声音,可如今却怎么也记不清了。 掉下来了。 我觉得,那一刻...

  • 《1+1=1-1》

    十一月十一日晚,致X小姐。 十月初九, 一个人购物的孤独, 你谈起, 月光下轧过的马路, 金钱带不来满足, 忙忙碌...

  • 1+1=-1

    结婚育子这几年,在磕磕碰碰中一路走来,才恍然大悟,自己真正的成长,始于育儿。 婚前是父母的公主,虽说家境贫困,却得...

  • 1+1<1

    也许有人看到我的标题就会来质疑我,说我怎么连最简单的数学都不会。1+1=2>1啊,这么简单的算数题,我怎会不知?但...

  • 1+1=-1

    看到他人发表文章,我也有点手痒痒了~这是接着上回文章的下半部分,有点长,没人看到就好了︿︿ 这个第二件小事的主题就...

  • 1⃣️0⃣️1⃣️1⃣️

    昨晚下了雨,早上雾蒙蒙。如画的烟雨曲江我们无暇欣赏,今天小伙伴都去了商场收资源,所以比较集中,真正起到了轰炸效果,...

网友评论

      本文标题:1

      本文链接:https://www.haomeiwen.com/subject/dqfnortx.html