java 缓存的简单实现_Java8简单的本地缓存实现
这里我将会给大家演示用ConcurrentHashMap类和lambda表达式实现一个本地缓存。因为Map有一个新的方法,在key为Null的时候自动计算一个新的value值。非常适合实现cache。来看下代码:
public static void main(String[] args) {
for (int i = 0; i < 10; i++)
System.out.println(
"f(" + i + ") = " + fibonacci(i));
}
static int fibonacci(int i) {
if (i == 0)
return i;
if (i == 1)
return 1;
System.out.println("Calculating f(" + i + ")");
return fibonacci(i - 2) + fibonacci(i - 1);
}
当然,这种方式很傻瓜。即使对于一个非常小的数,例如fibonacci(5),上面的代码也会打印出很多行,而且都是在进行重复计算,输出如下(只截取一部分):
Calculating f(6)
Calculating f(4)
Calculating f(2)
Calculating f(3)
Calculating f(2)
Calculating f(5)
Calculating f(3)
Calculating f(2)
Calculating f(4)
Calculating f(2)
Calculating f(3)
Calculating f(2)
f(6) = 8
我们想要做的就是创建一个缓存,用来计算斐波那契数列。最直接的方法就是在缓存中存放所有的value值。cache的创建如下:
static Map cache = new HashMap<>()
(译者注:这种写法在java8中是允许的)
声明cache之后,通过Map.computeIfAbsent() 方法,可以在key所对应的value值不存在的情况下,计算一个新的value值。超高速缓存(Caching)!由于这个方法是自动执行的,而且我们使用了 ConcurrentHashMap对象,这个缓存是线程安全的,不需要手动的去写同步方法。另外,它不仅仅可以处理斐波那契额数列,在其他地方也可以被重复使用。
不过现在,我们看看如何在fibonacci()方法中使用缓存。
static int fibonacci(int i) {
if (i == 0)
return i;
if (i == 1)
return 1;
return cache.computeIfAbsent(i, (key) ->
fibonacci(i - 2)
+ fibonacci(i - 1));
}
瞧瞧。不能比这个再简单了吧。想要证明吗?好吧,我们在每次计算一个新值的时候,加上些日志:
static int fibonacci(int i) {
if (i == 0)
return i;
if (i == 1)
return 1;
return cache.computeIfAbsent(i, (key) -> {
System.out.println(
"Slow calculation of " + key);
return fibonacci(i - 2) + fibonacci(i - 1);
});
}
程序输出如下:
f(0) = 0
f(1) = 1
Slow calculation of 2
f(2) = 1
Slow calculation of 3
f(3) = 2
Slow calculation of 4
f(4) = 3
Slow calculation of 5
f(5) = 5
Slow calculation of 6
f(6) = 8
Slow calculation of 7
f(7) = 13
Slow calculation of 8
f(8) = 21
Slow calculation of 9
f(9) = 34
在Java7下又如何实现呢?
这样代码就会多一些,我们可以使用double-checked locking来实现:
static int fibonacciJava7(int i) {
if (i == 0)
return i;
if (i == 1)
return 1;
Integer result = cache.get(i);
if (result == null) {
synchronized (cache) {
result = cache.get(i);
if (result == null) {
System.out.println(
"Slow calculation of " + i);
result = fibonacci(i - 2)
+ fibonacci(i - 1);
cache.put(i, result);
}
}
}
return result;
}
注:你实际的解决方案很可能会用到Guava Caches。
总结:Lambdas 表达式是Java8中非常重要的一部分。同时我们不要忘记那些新添加到库中的,可以和Lambdas 配合使用的特性。
java 缓存的简单实现_Java8简单的本地缓存实现相关推荐
- android分享图片功能实现原理,Android:简单实现并理解图片三级缓存
学习Android网络开发的过程中,势必会经历很多痛苦的过程,其中一个大坑就是图片缓存,当然现在有很多现成的库非常方便,常常几行代码就可以实现想要的功能,但不懂其中的原理是不行的,所以对于刚开始学习网 ...
- 本地缓存之Guava简单使用
文章目录 使用场景 Guava Cache 的优势 Guava Cache使用 CacheLoader Callable 删除 主动删除 过期删除 基于容量删除 引用删除 高级用法 并发设置 更新锁定 ...
- java本地缓存简介
java中的本地缓存,工作后陆续用到,一直想写,一直无从下手,最近又涉及到这方面的问题了,梳理了一下.自己构造单例.guava.ehcache基本上涵盖了目前的大多数行为了. 为什么要有本地缓存? 在 ...
- java 最少使用(lru)置换算法_一篇文章学会如何基于LRU-K算法设计本地缓存实现流量削峰...
专注于Java领域优质技术号,欢迎关注 作者:一个Java菜鸟 1.背景介绍 1.1.现象 QPS突然增长2倍以上(45w~60w每分钟) 将产生下面一些问题: 1)响应接口响应时长增加了5倍(qps ...
- Java高性能本地缓存框架Caffeine
文章目录 Java高性能本地缓存框架Caffeine 如何使用 缓存加载 手动加载 自动加载 手动异步加载 自动异步加载 过期策略 基于大小 基于时间 基于引用 Caffeine.weakKeys() ...
- 看了阿里大佬用的本地缓存,那叫一个优雅!
本文经授权转载自微信公众号:阿里开发者,作者:杨贤(临景) Java缓存技术可分为远端缓存和本地缓存,远端缓存常用的方案有著名的redis和memcache,而本地缓存的代表技术主要有HashMap, ...
- 基于LRU-K算法设计本地缓存实现流量削峰
1.背景介绍 1.1.现象 QPS突然增长2倍以上(45w~60w每分钟) 将产生下面一些问题: 1)响应接口响应时长增加了5倍(qps增加了2倍): 2)机房局域网交换机带宽报警(1kM带宽使用了9 ...
- 本地缓存:为什么要用本地缓存?用它会有什么问题?
背景 在高性能的服务架构设计中,缓存是一个不可或缺的环节.在实际的项目中,我们通常会将一些热点数据存储到Redis或Memcached 这类缓存中间件中,只有当缓存的访问没有命中时再查询数据库.在提升 ...
- 分布式缓存与本地缓存的区别
分布式缓存与本地缓存的区别 转载自:https://ost.51cto.com/posts/1002 缓存的概念: 在服务端中,缓存主要是指将数据库的数据加载到内存中,之后对该数据的访问都在内存中完成 ...
最新文章
- getCount()和getChildCount()区别
- php和python哪个做第二语言-php之后如何选择第二语言?
- 解决ntfs格式的移动硬盘mount到Linux下时变成只读文件系统的问题
- 设有n 个程序{1,2,…, n }要存放在长度为L的磁带上。程序i存放在磁带上的长度是Li, 1<= i<= n。这n 个程序的读取概率分别是p1,p2,...,pn,且pi+p2+...+pn =
- WPF/MVVM 快速开发
- mac 终端登陆linux,Mac终端自动登录服务器
- Python使用BoundedSemaphore对象进行线程同步
- uva 820 Internet Bandwidth
- ubuntu中wps缺失字体
- linux ubuntu 获取ip,linux系统(ubuntu)怎么查看ip地址
- c++程序调用python代码_使用C++调用Python代码的方法详解
- 锐捷客户端在linux下的校园网认证
- tomcat设置编码为UTF-8
- Vue+Element 表格打印
- Windows10官网原版系统下载地址汇总
- yaourt 查询时Segmentation fault package-query问题解决
- Excel 2010 VBA 入门 064 按照关键字批量创建超链接
- C# 使用 NPOI 处理Excel导入单元格内容是公式问题
- 《程序员修炼之道:从小工到专家》笔记-----第二章
- Vivado HLS常用优化命令介绍
热门文章
- caffe中的batchNorm层(caffe 中为什么bn层要和scale层一起使用)
- C#中Lambda表达式类型Expression不接受lambda函数
- Vsftpd文件传输服务(本地用户访问)
- Ubuntu 怎么增加根目录 大小
- 《程序员的修炼——从优秀到卓越》一一1.6 勿以专家自居
- android 开发中的常见问题
- logback常用配置
- Linux常用命令和服务器配置
- Linux下Socket 函数集(三)
- 安装SQL SERVER 2000时提示:以前的某个程序安装已在安装计算机上创建挂起的文件操作。...