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

    运行后的结果如下:

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

  • 相关阅读:
    Watchguard公司内部招聘:C Developer in Linux Requirements
    条件注释判断浏览器<![if !IE]><![if IE]><![if lt IE 6]><![if gte IE 6]>
    js之事件冒泡和事件捕获详细介绍
    javascript:;与javascript:void(0)使用介绍
    IE和FireFox中JS兼容之event .
    Adobe下周将推新补丁和新的更新模式 狼人:
    微软下周二发布11个补丁 修复25个安全漏洞 狼人:
    安全专家担心Adobe没有足够实力来阻止黑客攻击 狼人:
    保证安全 认清五种易被忽视的攻击方式 狼人:
    六成黑客攻击与PDF漏洞有关 远超微软 狼人:
  • 原文地址:https://www.cnblogs.com/loveyous/p/11403717.html
Copyright © 2020-2023  润新知