欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

java手写多级缓存

程序员文章站 2022-05-08 18:13:31
多级缓存实现类,时间有限,该类未抽取接口,目前只支持两级缓存:JVM缓存(实现 请查看上一篇:java 手写JVM高性能缓存)、redis缓存(在spring 的 redisTemplate 基础实现) redis缓存实现类 ......

 

多级缓存实现类,时间有限,该类未抽取接口,目前只支持两级缓存:jvm缓存(实现 请查看上一篇:java 手写jvm高性能缓存)、redis缓存(在spring 的 redistemplate 基础实现)

package com.ws.commons.cache;

import java.util.function.supplier;

import com.ws.commons.tool.threadtool;

/**
 * 多级缓存实现
 * 
 * @author 尘无尘
 *
 */
public class multilevelcache {

    private multilevelcache() {
    }

    private static final icache first_leve_lcache = localcache.instance();
    private static icache secondcache;

    private static final string lock_prefix = "muilcache_lock:";

    public static synchronized void init(icache secondcache) {
        if (multilevelcache.secondcache == null) {
            multilevelcache.secondcache = secondcache;
        }
    }

    public static void put(string key, object value, int timeoutsecond) {
        first_leve_lcache.put(key, value, timeoutsecond);
        if (secondcache != null) {
            secondcache.put(key, value, timeoutsecond);
        }
    }

    /**
     * 提供数据,并缓存
     * 
     * @param key
     * @param supplier
     * @return
     */
    @suppresswarnings("unchecked")
    public static <t> t getforload(string key, supplier<t> supplier) {
        t data = first_leve_lcache.get(key);
        if (data == null && secondcache != null) {
            data = (t) secondcache.get(key);
        }
        if (data != null) {
            return data;
        }

        synchronized (threadtool.buildlock(lock_prefix, key)) {
            data = first_leve_lcache.get(key);
            if (data == null && secondcache != null) {
                data = (t) secondcache.get(key);
            }
            if (data != null) {
                return data;
            }

            data = supplier.get();
            if (secondcache != null) {
                secondcache.put(key, data);
            }
            first_leve_lcache.put(key, data);
        }
        return data;
    }

    /**
     * 提供数据,并缓存一定的时间
     * 
     * @param key
     * @param timeoutsecond
     * @param supplier
     * @return
     */
    @suppresswarnings("unchecked")
    public static <t> t getforload(string key, int timeoutsecond, supplier<t> supplier) {
        t data = first_leve_lcache.get(key);
        if (data == null && secondcache != null) {
            data = (t) secondcache.get(key);
        }
        if (data != null) {
            return data;
        }
        synchronized (threadtool.buildlock(lock_prefix, key)) {
            data = first_leve_lcache.get(key);
            if (data == null && secondcache != null) {
                data = (t) secondcache.get(key);
            }
            if (data != null) {
                return data;
            }
            data = supplier.get();
            if (secondcache != null) {
                secondcache.put(key, data, timeoutsecond);
            }
            first_leve_lcache.put(key, data, timeoutsecond);
        }
        return data;
    }

    @suppresswarnings("unchecked")
    public static <t> t removeandget(string key) {
        t data = null;
        if (secondcache != null) {
            data = (t) secondcache.removeandget(key);
        }
        t data2 = first_leve_lcache.removeandget(key);
        if (data == null) {
            data = data2;
        }
        return data;
    }

    public static void remove(string key) {
        if (secondcache != null) {
            secondcache.remove(key);
        }
        first_leve_lcache.remove(key);
    }

    @suppresswarnings("unchecked")
    public static <t> t get(string key) {
        t data = first_leve_lcache.get(key);
        if (data == null && secondcache != null) {
            data = (t) secondcache.get(key);
        }
        return data;
    }

    public static void expire(string key, int timeoutsecond) {
        first_leve_lcache.expire(key, timeoutsecond);
        if (secondcache != null) {
            secondcache.expire(key, timeoutsecond);
        }
    }

}

 

redis缓存实现类

package com.walmart.cirular.interfaces.application;

import java.util.concurrent.timeunit;

import org.springframework.beans.factory.annotation.autowired;
import org.springframework.data.redis.core.redistemplate;
import org.springframework.stereotype.component;

import com.ws.commons.cache.icache;

/**
 * redis 缓存实现类
 * 
 * @author 尘无尘
 *
 */
@component
public class redisicacheimpl implements icache {

    @autowired(required = false)
    private redistemplate<string, object> redistemplate;

    @override
    public void put(string key, object value) {
        redistemplate.opsforvalue().set(key, value);
    }

    @override
    public void put(string key, object value, int timeoutsecond) {
        redistemplate.opsforvalue().set(key, value, (long) timeoutsecond, timeunit.seconds);
    }

    @suppresswarnings("unchecked")
    @override
    public <t> t get(string key) {
        t t = (t) redistemplate.opsforvalue().get(key);
        redistemplate.delete(key);
        return t;
    }

    @override
    public void remove(string key) {
        redistemplate.delete(key);
    }

    @suppresswarnings("unchecked")
    @override
    public <t> t removeandget(string key) {
        object obj = get(key);
        redistemplate.delete(key);
        return (t) obj;
    }

    @override
    public void rightpush(string key, object value, int timeoutsecond) {
        redistemplate.opsforlist().rightpush(key, value);
        redistemplate.expire(key, timeoutsecond, timeunit.seconds);
    }

    @suppresswarnings("unchecked")
    @override
    public <t> t rightpop(string key) {
        return (t) redistemplate.opsforlist().rightpop(key);
    }

    @suppresswarnings("unchecked")
    @override
    public <t> t leftpop(string key) {
        return (t) redistemplate.opsforlist().leftpop(key);
    }

    @override
    public void leftpush(string key, object value) {
        redistemplate.opsforlist().leftpush(key, value);
    }

    @override
    public void rightpush(string key, object value) {
        redistemplate.opsforlist().rightpush(key, value);
    }

    @override
    public void expire(string key, int timeoutsecond) {
        redistemplate.expire(key, timeoutsecond, timeunit.seconds);
    }

    @override
    public boolean haskey(string key) {
        return redistemplate.haskey(key);
    }

    @override
    public boolean putifabsent(string key, object value) {
        return redistemplate.opsforvalue().setifabsent(key, value);
    }

    @override
    public boolean putifabsent(string key, object value, int timeoutsecond) {
        boolean flag = putifabsent(key, value);
        if (flag) {
            expire(key, timeoutsecond);
        }
        return flag;
    }

}