JUC-数据缓存模型

缓存架构在这里插入图片描述

package com.mldn.demo;

import java.util.Map;
import java.util.concurrent.*;

class News {
    private Long id ;
    private String title ;
    public News(Long id,String title){
        this.id = id ;
        this.title = title ;
    }

    @Override
    public String toString() {
        return "新闻ID:"+this.id+"、新闻内容:"+this.title;
    }
}

/**
 *进行缓存操作的实现类,可以进行指定数据的存储
 * @param <K> 描述缓存key数据类型,此类型一定是唯一的,可以方便查询的(数据库的缓存ID是唯一的)
 * @param <V> 描述进行数据缓存的内容项(VO类)
 */
class Cache<K,V> {
    private static final TimeUnit TIME = TimeUnit.SECONDS ;
    private static final long DELAY_SECOND = 2 ;//默认数据的缓存时间为2秒
    private Map<K,V> cacheObjects = new ConcurrentHashMap<>() ;//该缓存类型可以进行并发控制
    private BlockingQueue<DelavedItem<Pair>> queue = new DelayQueue<>();//定义阻塞队列
    //进行后台线程的启动
    public Cache(){
        Thread deamonThread = new Thread(()->{
            while (true){//不断等待队列弹出的数据
                try {
                    DelavedItem<Pair> item = Cache.this.queue.take() ;//获取队列中的数据
                    if(item !=null){//此时有数据进行弹出
                        Pair pair = item.getItem() ;//获取包装了当前KV的对象
                        Cache.this.cacheObjects.remove(pair.key,pair.value);
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"后台队列清理线程")  ;
        deamonThread.setDaemon(true);//设置为后台线程
        deamonThread.start();//线程启动
    }
    public void put(K key,V value)throws Exception{
        //一旦数据进行存放的时候,该数据有可能已经在队列中存在了,也有可能不存在
        // 如果数据在队列中存在,那么就可以将原始队列中的数据删除掉(避免重复)
        // 如果数据本身不在队列中,就将数据直接保存在队列中。
        V oldValue = this.cacheObjects.put(key,value) ;//数据保存同时返回原始旧数据
        if(oldValue !=null){//该key的数据之前已经存放过了
            this.queue.remove(oldValue) ;
        }
        this.queue.put(new DelavedItem<Pair>(new Pair(key,value),DELAY_SECOND,TIME));
    }
    public V get(K key){
        return this.cacheObjects.get(key) ;
    }
    //实现阻塞队列中要进行的数据封装
    private class Pair{
        private K key ;
        private V value ;

        public Pair(K key, V value) {
            this.key = key;
            this.value = value;
        }
    }
    //进行延迟队列的操作控制
    private class DelavedItem<T> implements Delayed{
        private T item ; //延迟队列缓存项
        private long delay ;//延迟时间
        private long expire ;//失效时间
        public DelavedItem(T item,long delay,TimeUnit time){
            this.item  = item ;//设置真实的操作数据
            this.delay = TimeUnit.MILLISECONDS.convert(delay,time) ;//以毫秒为单位进行控制
            this.expire = this.delay + System.currentTimeMillis() ;//设置失效时间
        }

        @Override
        public long getDelay(TimeUnit unit) {
            return unit.convert(this.expire - System.currentTimeMillis(),TimeUnit.MILLISECONDS);
        }

        @Override
        public int compareTo(Delayed o) {
            return (int) (this.delay-this.getDelay(TimeUnit.MILLISECONDS));
        }

        public T getItem() {
            return item;
        }
    }
}
public class JUUCDemo {
    public static void main(String[] args) throws Exception{
        Cache<Long,News> cache = new Cache<>() ;//后台线程启动了
        cache.put(0L,new News(0L,"熊二"));
        cache.put(1L,new News(1L,"张三"));
        cache.put(2L,new News(2L,"李四"));
        cache.put(3L,new News(3L,"王五"));
        cache.put(4L,new News(4L,"赵六"));
        cache.put(5L,new News(5L,"李七"));
        cache.put(6L,new News(6L,"朱八"));
        cache.put(7L,new News(7L,"童九"));
        System.out.println(cache.get(1l));
        TimeUnit.MILLISECONDS.sleep(1000);
        cache.put(1L,new News(1L,"张三"));
        TimeUnit.MILLISECONDS.sleep(2000);
        System.out.println(cache.get(1l));
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值