精华内容
下载资源
问答
  • 2019-08-27 18:25:48
    /**
     * 
     */
    package cn.xdl.utils.common;
    
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.Map;
    
    /**
     * @author liurui
     * @date 2019年8月27日
     */
    public class EasyCacheUtil {
    
    	// 缓存map
        private static Map<String, Object> cacheMap = new HashMap<String, Object>();
        // 缓存有效期map
        private static Map<String, Long> expireTimeMap = new HashMap<String, Long>();
     
     
        /**
         * 获取指定的value,如果key不存在或者已过期,则返回null
         * @param key
         * @return
         */
        public static Object get(String key) {
            if (!cacheMap.containsKey(key)) {
                return null;
            }
            if (expireTimeMap.containsKey(key)) {
                if (expireTimeMap.get(key) < System.currentTimeMillis()) { // 缓存失效,已过期
                    return null;
                }
            }
            return cacheMap.get(key);
        }
     
        /**
         * @param key
         * @param <T>
         * @return
         */
        @SuppressWarnings({ "unchecked" })
    	public static <T> T getT(String key) {
            Object obj = get(key);
            return obj == null ? null : (T) obj;
        }
     
        /**
         * 设置value(不过期)
         * @param key
         * @param value
         */
        public static void set(String key, Object value) {
            cacheMap.put(key, value);
        }
     
        /**
         * 设置value
         * @param key
         * @param value
         * @param millSeconds 过期时间(毫秒)
         */
        public static void set(final String key, Object value, int millSeconds) {
            final long expireTime = System.currentTimeMillis() + millSeconds;
            cacheMap.put(key, value);
            expireTimeMap.put(key, expireTime);
            if (cacheMap.size() > 2) { // 清除过期数据
                new Thread(new Runnable() {
                    public void run() {
                        // 此处若使用foreach进行循环遍历,删除过期数据,会抛出java.util.ConcurrentModificationException异常
                        Iterator<Map.Entry<String, Object>> iterator = cacheMap.entrySet().iterator();
                        while (iterator.hasNext()) {
                            Map.Entry<String, Object> entry = iterator.next();
                            if (expireTimeMap.containsKey(entry.getKey())) {
                                long expireTime = expireTimeMap.get(key);
                                if (System.currentTimeMillis() > expireTime) {
                                    iterator.remove();
                                    expireTimeMap.remove(entry.getKey());
                                }
                            }
                        }
                    }
                }).start();
            }
        }
     
        /**
         * key是否存在
         * @param key
         * @return
         */
        public static boolean isExist(String key) {
            return cacheMap.containsKey(key);
        }
     
     
        public static void main(String[] args) {
            EasyCacheUtil.set("testKey_1", "testValue_1");
            EasyCacheUtil.set("testKey_2", "testValue_2", 1);
            EasyCacheUtil.set("testKey_3", "testValue_3");
            EasyCacheUtil.set("testKey_4", "testValue_4", 1);
            Object testKey_2 = EasyCacheUtil.get("testKey_2");
            System.out.println(testKey_2);
        }
    
    }
    
    更多相关内容
  • 主要介绍了Java内存缓存工具Guava LoadingCache使用解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • 实现简单的Java内存缓存

    千次阅读 2019-11-28 17:27:04
    实现了一个简单的内存缓存: 元素个数有限 能自动移除最老的条目 通过插入顺序遍历它 是线程安全的集合 适用于读多写少的场景 基于组合优于继承的思想,封装了LinkedHashMap,并且只有在写操作的时候才进行加锁。 ...

    引言

    实现了一个简单的内存缓存:

    1. 元素个数有限
    2. 能自动移除最老的条目
    3. 通过插入顺序遍历它
    4. 是线程安全的集合
    5. 适用于读多写少的场景

    基于组合优于继承的思想,封装了LinkedHashMap,并且只有在写操作的时候才进行加锁。

    代码

    import java.util.*;
    import java.util.concurrent.locks.ReentrantLock;
    
    /**
     * 遍历顺序(values()方法)是插入顺序的缓存,并且具有CopyOnWrite性质
     * @param <K>
     * @param <V>
     */
    public class CopyOnWriteCache<K, V> {
        private  LinkedHashMap<K, V> core;
        private static final int MAX_ENTRIES = 10000;
    
        private final int maxSize;
    
        private volatile Map<K, V> view;
    
    
        private final transient ReentrantLock lock = new ReentrantLock();
    
        public CopyOnWriteCache() {
            this(MAX_ENTRIES);
        }
    
    
        public CopyOnWriteCache(int maxSize) {
            if (maxSize <= 0) {
                throw new IllegalArgumentException();
            }
            this.maxSize = maxSize;
            core = new LinkedHashMap<K, V>(maxSize) {
                @Override
                protected boolean removeEldestEntry(Map.Entry eldest) {
                    return size() > maxSize; //当超过最大条目数时,移除最老的
                }
            };
        }
    
        private CopyOnWriteCache(CopyOnWriteCache<K, V> that) {
            this.core = that.core;
            this.maxSize = that.maxSize;
        }
    
    
        public void put(K key, V val) {
            final ReentrantLock lock = this.lock;
            lock.lock();
            try {
            	//拷贝一份老的
                LinkedHashMap<K, V> newCore = new LinkedHashMap<K, V>(this.core) {
                    @Override
                    protected boolean removeEldestEntry(Map.Entry eldest) {
                        return size() > maxSize;
                    }
                };
                newCore.put(key, val);
                this.core = newCore;
                view = null;
            } finally {
                lock.unlock();
            }
        }
    
        public V get(K key) {
            return core.get(key);
        }
    
        public void clear() {
            final ReentrantLock lock = this.lock;
            lock.lock();
            try {
                this.core = new LinkedHashMap<K, V>(this.core) {
                    @Override
                    protected boolean removeEldestEntry(Map.Entry eldest) {
                        return size() > maxSize;
                    }
                };
                view = null;
            } finally {
                lock.unlock();
            }
        }
    
        public int size() {
            return core.size();
        }
    
        public Collection<V> values() {
            return getView().values();
        }
    
        public Set<Map.Entry<K, V>> entrySet() {
            return getView().entrySet();
        }
    
        public V remove(K key) {
            final ReentrantLock lock = this.lock;
            lock.lock();
            try {
                LinkedHashMap<K, V> newCore = new LinkedHashMap<K, V>(this.core) {
                    @Override
                    protected boolean removeEldestEntry(Map.Entry eldest) {
                        return size() > maxSize;
                    }
                };
                view = null;
                V v = newCore.remove(key);
                this.core = newCore;
                return v;
            } finally {
                lock.unlock();
            }
        }
    
        @Override
        public String toString() {
            return core.toString();
        }
    
        private Map<K, V> getView() {
            Map<K, V> result = view;
            if (result == null) {
                result = Collections.unmodifiableMap(core);
                view = result;
            }
            return result;
        }
    }
    
    展开全文
  • cache4j是一款轻量级java内存缓存框架,实现FIFO、LRU、TwoQueues缓存模型,使用非常方便。 cache4j为java开发者提供一种更加轻便的内存缓存方案,杀鸡焉用EhCache? 特性 支持并发。 使用简单。 因为简单,所以通用...
  • JAVA数据缓存之内存缓存

    千次阅读 2020-12-08 15:46:29
    java内存缓存其实就是本地缓存 , 实现方法一般是从数据库查询出需要缓存的数据然后放到map里 ,根据需求可分为增量缓存和全量缓存,核心思想就是将想要查询数据库的用户拦住,从内存缓存中拿到想要的数据返回给用户...

    JAVA数据缓存之内存缓存

    简要介绍

    java内存缓存其实就是本地缓存 , 实现方法一般是从数据库查询出需要缓存的数据然后放到map里 ,根据需求可分为增量缓存和全量缓存,核心思想就是将想要查询数据库的用户拦住,从内存缓存中拿到想要的数据返回给用户。

    使用场景

    1.前台查询用户量比较大, 一直去查数据库会对数据库造成压力。
    2.数据量比较大 从大数据量里边拿一小部分数据,一般是一个人的相关数据。
    3.非集群环境 集群环境使用内存缓存会使内存的使用量变化过大,集群环境数据量不是特别大推荐
    redis数据缓存 ,数据量过大使用mogoDB缓存。
    4.数据量特别大不建议使用,过度使用内存存储会对服务器造成压力。
    5.缓存之前一定得试一下你那个查询到底多少秒能查出来,如果查询都很慢,然后你又要求数据缓存做成实时的(比如一秒一刷)这样会造成线程队列堆积,这样会把服务直接刷死。

    特性

    1.直接使用JAVA内存缓存查询速度是比redis快的。
    2.不能持久化(mogoDB和redis可以持久化)。

    数据缓存前期准备

    数据缓存最不可或缺的步骤为定时任务,这里我们使用的是spring提供的定时任务 ,配合cron表达式实现定时刷新缓存, 真正的线上环境绝对不是只缓存一种数据,所以定时任务一定得是多线程的,不能为串行执行,所以需要进行如下配置。
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.scheduling.annotation.EnableScheduling;
    import org.springframework.scheduling.annotation.SchedulingConfigurer;
    import org.springframework.scheduling.config.ScheduledTaskRegistrar;
    
    import java.util.concurrent.Executor;
    import java.util.concurrent.Executors;
    
    /**
     * 没有此配置,则schedule为单线程串行执行
     */
    @Configuration
    @EnableScheduling
    public class ScheduleConfig implements SchedulingConfigurer {
    
        @Override
        public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
            taskRegistrar.setScheduler(taskExecutor());
        }
    
        //配置线程池---触发器和任务共用的
        @Bean(destroyMethod="shutdown")
        public Executor taskExecutor() {
            return Executors.newScheduledThreadPool(10);
        }
    }
    

    初始化数据

    使用数据缓存之前首先需要初始化好装数据的map和记录增量缓存的缓存时刻(写增量缓存的话是需要记录上一次缓存的时间,在这个时间之后的数据需要进行缓存),这两种数据都写成全局变量也就是定义在类里边方法上边。
    	//因为要使用增量缓存  首先初始化用到的时间
        private Timestamp firmDataTime = null;
        //初始化hashMap用来存储缓存值
        public static ConcurrentHashMap<Integer , Firm> firmData = new ConcurrentHashMap<>();
    

    全量缓存使用场景

    数据在一定时间内是不变的,或者在特定的时间进行改变然后一定时间内不改变(比如市场结算时候的分成数据,市场会在每天闭市后进行结算分成,意思是这个数据会在每天闭市后生成,并在下一次闭市前保持不变)

    全量缓存代码块简要解释

    从1号开始每天进行一次全量缓存 首先清理缓存,然后查数据库,然后把数据库的数据装到map里边,逻辑是比较简单的。

    全量缓存代码展示

    //全量缓存
        @Scheduled(cron = "0 0 0 1/1 * ? ")
        public void cacheAllFirm(){
            firmData = null;
            List<Firm> firms = firmRepo.findAll();
            ConcurrentHashMap<Integer , Firm> allFirmMap= new ConcurrentHashMap<>();
            for(Firm firm : firms){
                allFirmMap.put(firm.getFirmId() , firm);
            }
            firmData = allFirmMap;
        }
    

    增量缓存使用场景

    一般其实做数据缓存的话是使用增量缓存,核心思想就是只缓存修改或新增的数据,缓存的数据少了,自然速度就快了。

    增量缓存代码块简要解释

    这里写的是一个每三秒进行一次增量缓存,首先记录一下当前时间,然后减去一个缓冲时间(意思就是每次增量缓存需要多缓存一些,防止因为任务的执行或者数据的变动少缓存数据,这个缓冲时间一般设置成2秒3秒左右,不用担心会多缓存数据,因为map 的存储特性key是唯一的,不会重复存储)如果map是空的首先就得进行一次全量缓存,不为空才增量 只查询记录缓存时间之后的数据,并put到map里,每次装完数据记录一个时间。

    增量缓存代码展示

    @Scheduled(cron = "*/3 * * * * ? ")
        public void cacheFirm(){
            log.info("每三秒增量缓存一次firm");
            Long time = new Timestamp(System.currentTimeMillis()).getTime() - 3000;
            if(firmData.isEmpty()){
                List<Firm> v = firmRepo.findAll();
                //第一次缓存先全量缓存一次
                log.info("全量缓存开始");
                addDateFirm(v , time);
            }
            else{
                List<Firm> v = firmRepo.findAllByUpdateTimeAfterOrCreateTimeAfter(firmDataTime , firmDataTime);
                //进行增量缓存
                log.info("增量缓存开始");
                addDateFirm(v , time);
            }
        }
    
        private void addDateFirm(List<Firm> firms  , Long time){
            if(firms != null && firms.size() > 0 ){
                for(Firm firm : firms){
                    firmData.put(firm.getFirmId() , firm);
                }
            }
            firmDataTime = new Timestamp(time);
        }
    

    以下是内存缓存的全部测试代码(包括以上举的例子)

    controller

    import com.tjdami.zs.test.jpa.model.Firm;
    import com.tjdami.zs.test.service.TestService;
    import io.swagger.annotations.Api;
    import io.swagger.annotations.ApiOperation;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.RequestHeader;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    /**
     * @Auther: Zyy
     * @Date: 2020/12/7 10:34
     * @Description:
     */
    @Api(value = "测试服务", description = "通用测试服务")
    @RequestMapping("/test")
    @RestController
    @Slf4j
    public class TestController {
    
        @Autowired
        private TestService testService;
    
        @RequestMapping(value = "/cacheFirm")
        @ApiOperation(value = "查看客户信息", httpMethod = "POST", notes = "查看客户信息")
        public Firm distribute(@RequestHeader("firmId") String firmId) throws Exception {
            return testService.getFirmCache(Integer.valueOf(firmId));
        }
    
    
    
    
    
    
    }
    

    service

    import com.tjdami.zs.test.cache.TextCache;
    import com.tjdami.zs.test.jpa.model.Firm;
    import org.springframework.stereotype.Service;
    
    /**
     * @Auther: Zyy
     * @Date: 2020/12/7 11:02
     * @Description:
     */
    @Service
    public class TestService {
    
        public Firm getFirmCache(Integer firmId) throws Exception {
            Firm firm = TextCache.firmData.get(firmId);
            return firm;
        }
    }
    

    缓存核心

    import com.tjdami.zs.test.jpa.model.Firm;
    import com.tjdami.zs.test.jpa.repo.FirmRepo;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.scheduling.annotation.Scheduled;
    import org.springframework.stereotype.Component;
    
    import java.sql.Timestamp;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.concurrent.ConcurrentHashMap;
    
    /**
     * @Auther: Zyy
     * @Date: 2020/12/7 11:17
     * @Description:
     */
    @Component
    @Slf4j
    public class TextCache {
        @Autowired
        private FirmRepo firmRepo;
    
        //因为要使用增量缓存  首先初始化用到的时间
        private Timestamp firmDataTime = null;
        private Timestamp firmDataListTime = null;
        //初始化hashMap用来存储缓存值
        public static ConcurrentHashMap<Integer , Firm> firmData = new ConcurrentHashMap<>();
        //初始化一个存储firm集合的map集合
        public static ConcurrentHashMap<Integer , List<Firm>> firmDataList = new ConcurrentHashMap<>();
    
    
        @Scheduled(cron = "*/3 * * * * ? ")
        public void cacheFirm(){
            log.info("每三秒增量缓存一次firm");
            Long time = new Timestamp(System.currentTimeMillis()).getTime() - 3000;
            if(firmData.isEmpty()){
                List<Firm> v = firmRepo.findAll();
                //第一次缓存先全量缓存一次
                log.info("全量缓存开始");
                addDateFirm(v , time);
            }
            else{
                List<Firm> v = firmRepo.findAllByUpdateTimeAfterOrCreateTimeAfter(firmDataTime , firmDataTime);
                //进行增量缓存
                log.info("增量缓存开始");
                addDateFirm(v , time);
            }
        }
    
        private void addDateFirm(List<Firm> firms  , Long time){
            if(firms != null && firms.size() > 0 ){
                for(Firm firm : firms){
                    firmData.put(firm.getFirmId() , firm);
                }
            }
            firmDataTime = new Timestamp(time);
        }
    
    
        //全量缓存
        @Scheduled(cron = "0 0 0 1/1 * ? ")
        public void cacheAllFirm(){
            firmData = null;
            List<Firm> firms = firmRepo.findAll();
            ConcurrentHashMap<Integer , Firm> allFirmMap= new ConcurrentHashMap<>();
            for(Firm firm : firms){
                allFirmMap.put(firm.getFirmId() , firm);
            }
            firmData = allFirmMap;
        }
    }
    

    定时任务多线程配置

    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.scheduling.annotation.EnableScheduling;
    import org.springframework.scheduling.annotation.SchedulingConfigurer;
    import org.springframework.scheduling.config.ScheduledTaskRegistrar;
    
    import java.util.concurrent.Executor;
    import java.util.concurrent.Executors;
    
    /**
     * 没有此配置,则schedule为单线程串行执行
     */
    @Configuration
    @EnableScheduling
    public class ScheduleConfig implements SchedulingConfigurer {
    
        @Override
        public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
            taskRegistrar.setScheduler(taskExecutor());
        }
    
        //配置线程池---触发器和任务共用的
        @Bean(destroyMethod="shutdown")
        public Executor taskExecutor() {
            return Executors.newScheduledThreadPool(10);
        }
    }
    

    实体类

    import lombok.Data;
    import lombok.experimental.Accessors;
    
    import javax.persistence.*;
    import java.io.Serializable;
    
    @Data
    @Entity
    @Table(name = "firm")
    public class Firm implements Serializable {
    
    	@Id
    	@GeneratedValue
    
    	@Column(name = "firm_id")
    	private Integer firmId;
    
    	
    	@Column(name = "firm_name")
    	private String firmName;
    
    
    	@Column(name = "create_time", insertable = false, updatable = false)
    	private java.sql.Timestamp createTime;
    
    	@Column(name = "update_time", insertable = false, updatable = false)
    	private java.sql.Timestamp updateTime;
    
    }
    

    JPA

    import com.tjdami.zs.test.jpa.model.Firm;
    import org.springframework.data.jpa.repository.JpaRepository;
    import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
    import org.springframework.data.jpa.repository.Modifying;
    import org.springframework.data.jpa.repository.Query;
    
    import java.sql.Timestamp;
    import java.util.List;
    import java.util.Map;
    
    public interface FirmRepo extends JpaRepository<Firm, Integer>, JpaSpecificationExecutor<Firm> {
     
        List<Firm> findAllByUpdateTimeAfterOrCreateTimeAfter(Timestamp timea , Timestamp timeb);
        
    }
    

    以上就是本期的全部内容了,操作数据库的技术为JPA加哈伯奈特,换成mybatis或者jdbc也是一样的简单哦,如果大家觉得有帮助一定记得动动小手点个赞。

    展开全文
  • 在工作总常常需要用到缓存,而redis往往是首选,但是短期的数据缓存一般我们还是会用到本地缓存。本文提供一个我在工作中用到的缓存工具,该工具代码为了演示做了一些调整。如果拿去使用的话,可以考虑做成注入Bean...

    目录

    前言

    环境依赖

    代码

    总结


    前言

    在工作总常常需要用到缓存,而redis往往是首选,但是短期的数据缓存一般我们还是会用到本地缓存。本文提供一个我在工作中用到的缓存工具,该工具代码为了演示做了一些调整。如果拿去使用的话,可以考虑做成注入Bean对象,看具体需求了。

    环境依赖

    先添加maven依赖

    .

            <dependency>
                <groupId>com.google.guava</groupId>
                <artifactId>guava</artifactId>
                <version>30.1.1-jre</version>
            </dependency>
            <dependency>
                <groupId>cn.hutool</groupId>
                <artifactId>hutool-all</artifactId>
                <version>5.5.2</version>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <optional>true</optional>
            </dependency>

    代码

    不废话,上代码了。

    package ai.guiji.csdn.tools;
    
    import cn.hutool.core.thread.ThreadUtil;
    import com.google.common.cache.*;
    import lombok.extern.slf4j.Slf4j;
    
    import java.text.MessageFormat;
    import java.util.Map;
    import java.util.concurrent.TimeUnit;
    import java.util.function.Consumer;
    import java.util.function.Function;
    import java.util.stream.LongStream;
    
    /** @Author 剑客阿良_ALiang @Date 2021/12/30 17:57 @Description: 缓存工具 */
    @Slf4j
    public class CacheUtils {
    
      private static LoadingCache<Long, String> cache;
    
      /**
       * 初始化缓存方法
       *
       * @param totleCount 缓存池上限
       * @param overtime 超时时间
       * @param unit 时间单位
       * @param handleNotExist 处理不存在key方法
       * @param handleRemove 移除主键消费
       */
      private static void initCache(
          Integer totleCount,
          Integer overtime,
          TimeUnit unit,
          Function<Long, String> handleNotExist,
          Consumer<Long> handleRemove) {
        cache =
            CacheBuilder.newBuilder()
                // 缓存池大小
                .maximumSize(totleCount)
                // 设置时间对象没有被读/写访问则对象从内存中删除
                .expireAfterWrite(overtime, unit)
                // 移除监听器
                .removalListener(
                    new RemovalListener<Long, String>() {
                      @Override
                      public void onRemoval(RemovalNotification<Long, String> rn) {
                        handleRemove.accept(rn.getKey());
                      }
                    })
                .recordStats()
                .build(
                    new CacheLoader<Long, String>() {
                      @Override
                      public String load(Long aLong) throws Exception {
                        return handleNotExist.apply(aLong);
                      }
                    });
        log.info("初始化缓存");
      }
    
      /**
       * 存入缓存
       *
       * @param key 键
       * @param value 值
       */
      public static void put(Long key, String value) {
        try {
          log.info("缓存存入:[{}]-[{}]", key, value);
          cache.put(key, value);
        } catch (Exception exception) {
          log.error("存入缓存异常", exception);
        }
      }
    
      /**
       * 批量存入缓存
       *
       * @param map 映射
       */
      public static void putMap(Map<Long, String> map) {
        try {
          log.info("批量缓存存入:[{}]", map);
          cache.putAll(map);
        } catch (Exception exception) {
          log.error("批量存入缓存异常", exception);
        }
      }
    
      /**
       * 获取缓存
       *
       * @param key 键
       */
      public static String get(Long key) {
        try {
          return cache.get(key);
        } catch (Exception exception) {
          log.error("获取缓存异常", exception);
          return null;
        }
      }
    
      /**
       * 删除缓存
       *
       * @param key 键
       */
      public static void removeKey(Long key) {
        try {
          cache.invalidate(key);
        } catch (Exception exception) {
          log.error("删除缓存异常", exception);
        }
      }
    
      /**
       * 批量删除缓存
       *
       * @param keys 键
       */
      public static void removeAll(Iterable<Long> keys) {
        try {
          cache.invalidateAll(keys);
        } catch (Exception exception) {
          log.error("批量删除缓存异常", exception);
        }
      }
    
      /** 清理缓存 */
      public static void clear() {
        try {
          cache.invalidateAll();
        } catch (Exception exception) {
          log.error("清理缓存异常", exception);
        }
      }
    
      /**
       * 获取缓存大小
       *
       * @return 长度
       */
      public static long size() {
        return cache.size();
      }
    
      public static void main(String[] args) {
        initCache(
            Integer.MAX_VALUE,
            10,
            TimeUnit.SECONDS,
            k -> {
              log.info("缓存:[{}],不存在", k);
              return "";
            },
            x -> log.info("缓存:[{}],已经移除", x));
        System.out.println(size());
        LongStream.range(0, 10).forEach(a -> put(a, MessageFormat.format("tt-{0}", a)));
        System.out.println(cache.asMap());
        ThreadUtil.sleep(5000);
        LongStream.range(0, 10)
            .forEach(
                a -> {
                  System.out.println(get(a));
                  ThreadUtil.sleep(1000);
                });
        System.out.println(cache.asMap());
        ThreadUtil.sleep(10000);
        System.out.println(cache.asMap());
      }
    }
    

    代码说明

    1、在初始化loadingCache的时候,可以添加缓存的最大数量、消逝时间、消逝或者移除监听事件、不存在键处理等等。在上面的代码中,我初始化缓存大小为Integer的最大值,写入10秒后消逝,如不存在key返回空字符串等等。

    2、该类也提供了put、putAll、get、remove、removeAll、clear、size方法,可以对缓存进行存、取、删、清理、大小等操作。

    3、main演示方法中,先往缓存存入10个数据,然后过5秒后每秒取一个数据,并且打印一下缓存中的全部内容。

    4、补充一句LoadingCache是线程安全的哦。

    演示一下

    15:31:53.495 [main] INFO ai.guiji.csdn.tools.CacheUtils - 初始化缓存
    0
    15:31:53.502 [main] INFO ai.guiji.csdn.tools.CacheUtils - 缓存存入:[0]-[tt-0]
    15:31:53.508 [main] INFO ai.guiji.csdn.tools.CacheUtils - 缓存存入:[1]-[tt-1]
    15:31:53.508 [main] INFO ai.guiji.csdn.tools.CacheUtils - 缓存存入:[2]-[tt-2]
    15:31:53.508 [main] INFO ai.guiji.csdn.tools.CacheUtils - 缓存存入:[3]-[tt-3]
    15:31:53.508 [main] INFO ai.guiji.csdn.tools.CacheUtils - 缓存存入:[4]-[tt-4]
    15:31:53.508 [main] INFO ai.guiji.csdn.tools.CacheUtils - 缓存存入:[5]-[tt-5]
    15:31:53.508 [main] INFO ai.guiji.csdn.tools.CacheUtils - 缓存存入:[6]-[tt-6]
    15:31:53.508 [main] INFO ai.guiji.csdn.tools.CacheUtils - 缓存存入:[7]-[tt-7]
    15:31:53.509 [main] INFO ai.guiji.csdn.tools.CacheUtils - 缓存存入:[8]-[tt-8]
    15:31:53.509 [main] INFO ai.guiji.csdn.tools.CacheUtils - 缓存存入:[9]-[tt-9]
    {6=tt-6, 5=tt-5, 0=tt-0, 8=tt-8, 7=tt-7, 2=tt-2, 1=tt-1, 9=tt-9, 3=tt-3, 4=tt-4}
    tt-0
    tt-1
    tt-2
    tt-3
    tt-4
    15:32:03.572 [main] INFO ai.guiji.csdn.tools.CacheUtils - 缓存:[5],已经移除
    15:32:03.573 [main] INFO ai.guiji.csdn.tools.CacheUtils - 缓存:[6],已经移除
    15:32:03.573 [main] INFO ai.guiji.csdn.tools.CacheUtils - 缓存:[5],不存在

    15:32:04.581 [main] INFO ai.guiji.csdn.tools.CacheUtils - 缓存:[6],不存在

    15:32:05.589 [main] INFO ai.guiji.csdn.tools.CacheUtils - 缓存:[0],已经移除
    15:32:05.589 [main] INFO ai.guiji.csdn.tools.CacheUtils - 缓存:[7],已经移除
    15:32:05.589 [main] INFO ai.guiji.csdn.tools.CacheUtils - 缓存:[8],已经移除
    15:32:05.589 [main] INFO ai.guiji.csdn.tools.CacheUtils - 缓存:[7],不存在

    15:32:06.589 [main] INFO ai.guiji.csdn.tools.CacheUtils - 缓存:[8],不存在

    15:32:07.591 [main] INFO ai.guiji.csdn.tools.CacheUtils - 缓存:[1],已经移除
    15:32:07.591 [main] INFO ai.guiji.csdn.tools.CacheUtils - 缓存:[2],已经移除
    15:32:07.591 [main] INFO ai.guiji.csdn.tools.CacheUtils - 缓存:[9],已经移除
    15:32:07.591 [main] INFO ai.guiji.csdn.tools.CacheUtils - 缓存:[9],不存在

    {6=, 5=, 8=, 7=, 9=}
    {}

    Process finished with exit code 0
     

    可以看到,后面的5-9在内存中已经不存在对应的值了。

    总结

    本文提供的工具代码主要是为了演示,实际工作中可以按照自己的需求做调整。

     还有补充一下,最近博主在参加评选博客之星活动。如果你喜欢我的文章的话,不妨给我点个五星,投投票吧,谢谢大家的支持!!链接地址:https://bbs.csdn.net/topics/603956455

    分享:

            在梦中,我以为人生很漫长,会远得连尽头也看不见,没想到我匆匆翻看,人生,却再也无法逆转。在当下,我以为时间很重,会重得连时针都走不动。 没想到我轻轻一吹,时间,却再也没回来过。——《言叶之庭》

    如果本文对你有帮助的话,点个赞吧,谢谢!!

    展开全文
  • Java三个类实现内存缓存

    万次阅读 2016-08-06 14:51:21
    有一个需求,本来打算用redis来做,但是发现redis的list不支持某一项超时设置, 所以就用java自己写了一个简单的缓存,操作类似redis,总共只有3...简单的内存缓存实现,实现group概念,一个group里面是个有序的集合,
  • Java 缓存工具类 Cache

    千次阅读 2022-04-07 22:54:43
    Java 缓存工具类 Cache工具类定义
  • 主要介绍了Java中常用缓存Cache机制的实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • cache2k, 轻量级,高性能的Java缓存 cache2k缓存cache2k是内存高性能的Java缓存库。 Cache,String> cache = new Cache2kBuilder, String>
  • java中的缓存详解,一篇就够了

    千次阅读 2022-02-28 10:09:01
    2G MySQL建议buffer pool开大到服务器物理内存60-80% 五、应用程序缓存 1、对象缓存 由O/R Mapping框架例如Hibernate提供,透明性访问,细颗粒度缓存数据库查询结果,无需业务代码显式编程,是最省事的缓存策略 当...
  • java实现带过期时间的缓存

    千次阅读 2021-02-28 16:19:07
    /** * 让过期时间最小的数据排在队列前,在清除过期数据时 * ,只需查看缓存最近的过期数据,而不用扫描全部缓存 * * @see Node#compareTo(Node) * @see SwapExpiredNodeWork#run() */ private PriorityQueue ...
  • 该项目实现了一个缓存模拟器,可用于研究和比较各种缓存配置的有效性。 我的模拟器将读取给定文件中的内存访问跟踪,并根据某些参数来模拟根据这些内存访问模式进行的缓存将执行的操作
  • java中常用的缓存框架

    千次阅读 2019-10-10 23:05:04
    阅读文本大概需要3分钟。0x01:Ehcache Ehcache是一个Java实现的开源分布式缓存框架,EhCache可以有效地减轻数据库的负载,可以让数据保存在不同服...
  • Java中缓存之内存缓存

    万次阅读 2016-04-08 17:04:05
    Java中缓存之内存缓存 1.缓存为什么要存在  应用服务器资源是有限的,数据库每秒中接受请求的次数也是有限的。如果利用有限的资源来提供尽可能大的吞吐量呢,一个办法:减少计 算量,缩短请求流程(减少网络io或者硬盘...
  • Java 内存缓存数据(map实现)

    千次阅读 2019-03-21 11:25:44
    方式一:单一容器存储 import java.util.Date; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; ... * @Title: WeatherCacheUtils ... * @Description: 常用数据缓存工具 * @a...
  • 数据缓存Java实现

    千次阅读 2019-02-15 17:13:04
     对于缓存大家应该都不陌生,缓存的核心是用空间换实践,通过分配一块高速存储区域(一般都是内存)来提高数据的读写效率,其实现的难点在于清空策略的实现,比较合理的思路就是定时回收与及时判断数据是否过期相...
  • 内存缓存>Redis缓存>数据库

    千次阅读 2018-03-14 21:00:49
    情况描述:  有以下几张表,单据表(t_bill)、货物表(t_cargo)、原料表(t_raw_material)、配置表(t_...我写这篇文章的目的在于想告诉大家,内存的性能大于Redis缓存,Redis缓存性能大于数据库直接查询。
  • java缓存数据并配置有效时间

    千次阅读 2020-06-15 10:50:01
    没有用到redis 只是单纯的使用内存存储数据 实现的功能:缓存数据并配置有效时间,可设置默认时间自动清除缓存,也可以自己设置。 直接上代码: import java.util.LinkedList; import java.util.List; import java....
  • 3. java缓存-线程内缓存guava cache

    千次阅读 2018-09-25 16:12:03
    guava cache的缓存结构 常用的guava cache缓存 根据上图中的缓存框架,我们常用的一些缓存实例有:LocalManualCache和LocalLoadingCache,两者唯一的区别就是LocalLoadingCache extends LocalManualCache ...
  • 缓存就是数据交换的缓冲区(称作:Cache),当某一硬件要读取数据时,会首先从缓存汇总查询数据,有则直接执行,不存在时从内存中获取。由于缓存的数据比内存快的多,所以缓存的作用就是帮助硬件更快的运行 二、为...
  • 统计缓存大小(查看java对象所占的内存大小).
  • 为您提供EhcacheJava缓存框架下载,EhCache 是一个纯Java的进程内缓存框架,具有快速、精干等特点,是Hibernate中默认的CacheProvider。主要的特性有:1. 快速.2. 简单.3. 多种缓存策略4. 缓存数据有两级:内存和...
  • 参数 total: 内存总数 ... -/+ buffers/cache:基于应用角度考虑(计算已使用内存时减去buffers/cache,计算可使用内存时加上buffers/cache)的内存情况,也可理解为真实的内存使用情况. Swap: 交换分区 然后e.
  • java Map实现的cache manager,定时清除缓存里面的值,使数据一致保持最新
  • 目前支持内存、堆外内存、磁盘缓存。 功能特点: 支持二级缓存:Memory、Persistence 各个缓存可以拥有有效时间,超过时间缓存会过期 Memory 默认支持 FIFO、LRU、LFU 算法的实现 Memory 额外支持 Guava Cache、...
  • java管理windows系统内存_java释放内存缓存_java获得CPU使用率_系统内存_硬盘_进程源代码
  • CPU缓存Java内存模型

    千次阅读 2018-09-19 20:45:47
    CPU多级缓存 局部性原理: 1)时间局部性:如果某个数据被访问,那么在不久的将来它很可能再次被访问;...这行数据有效,数据被修改了,和内存中的数据不一致,数据只存在于本Cache中。 E(Exclus...
  • java本地缓存

    千次阅读 2020-12-23 15:24:23
    实现本地缓存,存储容器肯定是 key/value 形式的数据结构,在 Java 中,也就是我们常用的 Map 集合。Map 中有 HashMap、Hashtable、ConcurrentHashMap 几种供我们选择,如果不考虑高并发情况下数据安全问题,我们...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 468,360
精华内容 187,344
关键字:

java内存缓存

java 订阅