java手写多级缓存
多级缓存实现类,时间有限,该类未抽取接口,目前只支持两级缓存:JVM缓存(实现 请查看上一篇:java 手写JVM高性能缓存)、redis缓存(在spring 的 redisTemplate 基础实现)
package com.ws.commons.cache; import java.util.function.Supplier; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import com.ws.commons.tool.ThreadTool; /**
* 多级缓存实现
*
* @author 尘无尘
*
*/
public class MultilevelCache {
private static final Logger LOGGER = LoggerFactory.getLogger(MultilevelCache.class); 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;
LOGGER.info("开启二级缓存,secondCache:{}", secondCache);
}
} public static void put(String key, Object value, int timeOutSecond) {
if (secondCache != null) {
secondCache.put(key, value, timeOutSecond);
FIRST_LEVE_LCACHE.put(key, value, cmpFirstCacheTimeOutSecond(timeOutSecond));
} else {
FIRST_LEVE_LCACHE.put(key, value, timeOutSecond);
}
} /**
* 提供数据,并缓存
*
* @param key
* @param supplier
* @return
*/
public static <T> T computeIfAbsent(String key, Supplier<T> supplier) {
T data = FIRST_LEVE_LCACHE.get(key);
if (data == null && secondCache != null) {
data = 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 = secondCache.get(key);
}
if (data != null) {
return data;
} data = supplier.get();
if (secondCache != null) {
secondCache.put(key, data);
FIRST_LEVE_LCACHE.put(key, data, 60);
} else {
FIRST_LEVE_LCACHE.put(key, data);
}
}
return data;
} /**
* 提供数据,并缓存一定的时间
*
* @param key
* @param timeOutSecond
* @param supplier
* @return
*/
public static <T> T computeIfAbsent(String key, int timeOutSecond, Supplier<T> supplier) {
T data = FIRST_LEVE_LCACHE.get(key);
if (data == null && secondCache != null) {
data = 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 = 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, cmpFirstCacheTimeOutSecond(timeOutSecond));
} else {
FIRST_LEVE_LCACHE.put(key, data, timeOutSecond);
} }
return data;
} public static <T> T removeAndGet(String key) {
T data = null;
if (secondCache != null) {
data = 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);
} public static <T> T get(String key) {
T data = FIRST_LEVE_LCACHE.get(key);
if (data == null && secondCache != null) {
data = 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);
}
} private static int cmpFirstCacheTimeOutSecond(int timeOutSecond) {
if (timeOutSecond > 60) {
return 60;
} else if (timeOutSecond > 30) {
return timeOutSecond / 2;
}
return timeOutSecond;
}
}
java手写多级缓存的更多相关文章
- java 手写 jvm高性能缓存
java 手写 jvm高性能缓存,键值对存储,队列存储,存储超时设置 缓存接口 package com.ws.commons.cache; import java.util.function.Func ...
- 教你如何使用Java手写一个基于链表的队列
在上一篇博客[教你如何使用Java手写一个基于数组的队列]中已经介绍了队列,以及Java语言中对队列的实现,对队列不是很了解的可以我上一篇文章.那么,现在就直接进入主题吧. 这篇博客主要讲解的是如何使 ...
- Java:手写幼儿园级线程安全LRU缓存X探究影响命中率的因素
最近遇到一个需求,需要频繁访问数据库,但是访问的内容只是 id + 名称 这样的简单键值对. 频繁的访问数据库,网络上和内存上都会给数据库服务器带来不小负担. 于是打算写一个简单的LRU缓存来缓存这样 ...
- 利用Java手写简单的httpserver
前言: 在看完尚学堂JAVA300中讲解如何实现一个最简单的httpserver部分的视频之后, 一.前置知识 1.HTTP协议 当前互联网网页访问主要采用了B/S的模式,既一个浏览器,一个服务器,浏 ...
- HashMap+双向链表手写LRU缓存算法/页面置换算法
import java.util.Hashtable; class DLinkedList { String key; //键 int value; //值 DLinkedList pre; //双向 ...
- 教你如何使用Java手写一个基于数组实现的队列
一.概述 队列,又称为伫列(queue),是先进先出(FIFO, First-In-First-Out)的线性表.在具体应用中通常用链表或者数组来实现.队列只允许在后端(称为rear)进行插入操作,在 ...
- java手写线程池,完善中
package com.test001.threadpool; import java.util.LinkedList; import java.util.List; import java.util ...
- Java手写简单HashMap一(包括增加,查找,toString,泛型)
@Java 300 学习总结 HashMap底层采用实现采用了哈希表,结合了"数组和链表". 原理如图 一.定义HashMap类. 首先需要定义一个节点来存储数据,构成链表结构. ...
- java手写的动态数组JimisunArray
/** * @Author:jimisun * @Description: * @Date:Created in 22:10 2018-07-18 * @Modified By: */ public ...
随机推荐
- vue-router路由嵌套与二级路由重定向
(1)公共路由裁减 不是每个页面都存在导航,所以不要把导航组件在根组件APP.vue里引入,哪个页面需要,在哪里引入即可. 方案: 哪个页面需要,在哪个页面引入即可 (2)嵌套路由 注意:childr ...
- 十大排序算法总结(Python3实现)
十大排序算法总结(Python3实现) 本文链接:https://blog.csdn.net/aiya_aiya_/article/details/79846380 目录 一.概述 二.算法简介及代码 ...
- 15-C#笔记-结构体
示例: using System; using System.Text; struct Books { private string title; // 支持 public private strin ...
- split分割字符串返回字符串数组
<script type="text/javascript"> var str='liu jin yu'; var str1=str.split(' '); docum ...
- NOIP 2004 联合权值
洛谷 P1351 联合权值 洛谷传送门 JDOJ 2886: [NOIP2014]联合权值 D1 T2 JDOJ传送门 Description 无向连通图 G有 n个点,n-1条边.点从 1到 n依次 ...
- 小学四则运算口算练习app---No.3
今天主要是实现按照指定的题目出题数目出题.在昨天设置页面的基础上,今天首先要学习的是接收不同页面间的参数问题.详解如下: 然后就开始我的传参和接收参数的问题! 在当前的Activity上进行跳转, 代 ...
- qt ubutun各个版本下载地址
http://download.qt.io/archive/qt/ http://mirrors.melbourne.co.uk/ubuntu-releases/
- 洛谷P1531 I Hate It题解
题目背景 很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少.这让很多学生很反感. 题目描述 不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模拟老师的 ...
- 数据结构与算法系列——排序(4)_Shell希尔排序
1. 工作原理(定义) 希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本.但希尔排序是非稳定排序算法. 希尔排序的基本思想是:先将整个待排序的记录序列分割成为若干子序列分别进行直接插入 ...
- Makefile文件基本格式
以下是Makefile的基本模板 #指定编译器CC = g++#指定编译参数CFLAGS = -std=c++11 #指定头文件路径,此处用于指定非标准库的头文件路径INC = -I./ -I /us ...