• Java内存缓存-通过Google Guava创建缓存


    谷歌Guava缓存

    Guava介绍

    Guava是Google guava中的一个内存缓存模块,用于将数据缓存到JVM内存中。实际项目开发中经常将一些公共或者常用的数据缓存起来方便快速访问。

    Guava Cache是单个应用运行时的本地缓存。它不把数据存放到文件或外部服务器。如果不符合需求,可以选择Memcached、Redis等工具。

    小案例

    pom.xml添加guava依赖

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>me.xueyao.cache</groupId>
        <artifactId>java-demo</artifactId>
        <version>1.0.0</version>
    
        <dependencies>
            <dependency>
                <groupId>javax.cache</groupId>
                <artifactId>cache-api</artifactId>
                <version>1.1.0</version>
            </dependency>
    
            <dependency>
                <groupId>com.google.guava</groupId>
                <artifactId>guava</artifactId>
                <version>27.0.1-jre</version>
            </dependency>
        </dependencies>
    </project>
    

    GuavaCacheDemo.java 代码如下:

    package me.xueyao.cache.java.guava;
    
    import com.google.common.cache.*;
    import me.xueyao.cache.java.pojo.User;
    
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.TimeUnit;
    
    /**
     * @author simon
     * https://github.com/google/guava
     */
    public class GuavaCacheDemo {
        public static void main(String[] args) throws ExecutionException {
            //缓存接口这里是LoadingCache,LoadingCache在缓存项不存在时可以自动加载缓存
            LoadingCache<String, User> userCache
                    //CacheBuilder的构造函数是私有的,只能通过其静态方法newBuilder()来获得CacheBuilder的实例
                    = CacheBuilder.newBuilder()
                    //设置并发级别为8,并发级别是指可以同时写缓存的线程数
                    .concurrencyLevel(8)
                    //设置写缓存后8秒钟过期
                    .expireAfterWrite(8, TimeUnit.SECONDS)
                    //设置写缓存后1秒钟刷新
                    .refreshAfterWrite(1, TimeUnit.SECONDS)
                    //设置缓存容器的初始容量为5
                    .initialCapacity(5)
                    //设置缓存最大容量为100,超过100之后就会按照LRU最近虽少使用算法来移除缓存项
                    .maximumSize(100)
                    //设置要统计缓存的命中率
                    .recordStats()
                    //设置缓存的移除通知
                    .removalListener(new RemovalListener<Object, Object>() {
                        @Override
                        public void onRemoval(RemovalNotification<Object, Object> notification) {
                            System.out.println(notification.getKey() + " 被移除了,原因: " + notification.getCause());
                        }
                    })
                    //build方法中可以指定CacheLoader,在缓存不存在时通过CacheLoader的实现自动加载缓存
                    .build(
                            new CacheLoader<String, User>() {
                                @Override
                                public User load(String key) throws Exception {
                                    System.out.println("缓存没有时,从数据库加载" + key);
                                    return new User("tony" + key, key);
                                }
                            }
                    );
    
            // 第一次读取
            for (int i = 0; i < 10; i++) {
                User user = userCache.get("uid" + i);
                System.out.println(user);
            }
    
            // 第二次读取
            for (int i = 0; i < 10; i++) {
                User user = userCache.get("uid" + i);
                System.out.println(user);
            }
            System.out.println("cache stats:");
            //最后打印缓存的命中率等 情况
            System.out.println(userCache.stats().toString());
        }
    }
    

    User.java 代码如下:

    package me.xueyao.cache.java.pojo;
    
    import java.io.Serializable;
    
    /**
     * @author simon
     */
    public class User implements Serializable {
        private String userName;
        private String userId;
    
        public User(String userName, String userId) {
            this.userName = userName;
            this.userId = userId;
        }
    
        public String getUserId() {
            return userId;
        }
    
        public void setUserId(String userId) {
            this.userId = userId;
        }
    
        public String getUserName() {
            return userName;
        }
    
        @Override
        public String toString() {
            return userId + " --- " + userName;
        }
    }
    

    运行后的结果如下:

    第一次循环时缓存中没有数据,构建了缓存,第二次直接命中缓存。如果程序需要单机内存缓存,可以用该方式构建缓存。

  • 相关阅读:
    javascript的字段值,私有变量,静态方法声明
    取得序列中某个点的范围边界
    使用wubi安装ubuntu11.04后无线网卡被禁用无法打开解决办法
    WEB前端性能优化
    jQuery的arrayLike
    在手机上安装BT5系统,没错就是破解无线密码的那个
    PHP在子类方法B调用父类的方法A时,不传参数时仍能得到方法B的名称
    讨厌的文本选区
    PHP遍历解析XML为一个数组
    “软工厂代码生成工具”的学习笔记
  • 原文地址:https://www.cnblogs.com/loveyous/p/11403717.html
Copyright © 2020-2023  润新知