这里我将会给大家演示用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简单的本地缓存实现相关推荐

  1. android分享图片功能实现原理,Android:简单实现并理解图片三级缓存

    学习Android网络开发的过程中,势必会经历很多痛苦的过程,其中一个大坑就是图片缓存,当然现在有很多现成的库非常方便,常常几行代码就可以实现想要的功能,但不懂其中的原理是不行的,所以对于刚开始学习网 ...

  2. 本地缓存之Guava简单使用

    文章目录 使用场景 Guava Cache 的优势 Guava Cache使用 CacheLoader Callable 删除 主动删除 过期删除 基于容量删除 引用删除 高级用法 并发设置 更新锁定 ...

  3. java本地缓存简介

    java中的本地缓存,工作后陆续用到,一直想写,一直无从下手,最近又涉及到这方面的问题了,梳理了一下.自己构造单例.guava.ehcache基本上涵盖了目前的大多数行为了. 为什么要有本地缓存? 在 ...

  4. java 最少使用(lru)置换算法_一篇文章学会如何基于LRU-K算法设计本地缓存实现流量削峰...

    专注于Java领域优质技术号,欢迎关注 作者:一个Java菜鸟 1.背景介绍 1.1.现象 QPS突然增长2倍以上(45w~60w每分钟) 将产生下面一些问题: 1)响应接口响应时长增加了5倍(qps ...

  5. Java高性能本地缓存框架Caffeine

    文章目录 Java高性能本地缓存框架Caffeine 如何使用 缓存加载 手动加载 自动加载 手动异步加载 自动异步加载 过期策略 基于大小 基于时间 基于引用 Caffeine.weakKeys() ...

  6. 看了阿里大佬用的本地缓存,那叫一个优雅!

    本文经授权转载自微信公众号:阿里开发者,作者:杨贤(临景) Java缓存技术可分为远端缓存和本地缓存,远端缓存常用的方案有著名的redis和memcache,而本地缓存的代表技术主要有HashMap, ...

  7. 基于LRU-K算法设计本地缓存实现流量削峰

    1.背景介绍 1.1.现象 QPS突然增长2倍以上(45w~60w每分钟) 将产生下面一些问题: 1)响应接口响应时长增加了5倍(qps增加了2倍): 2)机房局域网交换机带宽报警(1kM带宽使用了9 ...

  8. 本地缓存:为什么要用本地缓存?用它会有什么问题?

    背景 在高性能的服务架构设计中,缓存是一个不可或缺的环节.在实际的项目中,我们通常会将一些热点数据存储到Redis或Memcached 这类缓存中间件中,只有当缓存的访问没有命中时再查询数据库.在提升 ...

  9. 分布式缓存与本地缓存的区别

    分布式缓存与本地缓存的区别 转载自:https://ost.51cto.com/posts/1002 缓存的概念: 在服务端中,缓存主要是指将数据库的数据加载到内存中,之后对该数据的访问都在内存中完成 ...

最新文章

  1. getCount()和getChildCount()区别
  2. php和python哪个做第二语言-php之后如何选择第二语言?
  3. 解决ntfs格式的移动硬盘mount到Linux下时变成只读文件系统的问题
  4. 设有n 个程序{1,2,…, n }要存放在长度为L的磁带上。程序i存放在磁带上的长度是Li, 1<= i<= n。这n 个程序的读取概率分别是p1,p2,...,pn,且pi+p2+...+pn =
  5. WPF/MVVM 快速开发
  6. mac 终端登陆linux,Mac终端自动登录服务器
  7. Python使用BoundedSemaphore对象进行线程同步
  8. uva 820 Internet Bandwidth
  9. ubuntu中wps缺失字体
  10. linux ubuntu 获取ip,linux系统(ubuntu)怎么查看ip地址
  11. c++程序调用python代码_使用C++调用Python代码的方法详解
  12. 锐捷客户端在linux下的校园网认证
  13. tomcat设置编码为UTF-8
  14. Vue+Element 表格打印
  15. Windows10官网原版系统下载地址汇总
  16. yaourt 查询时Segmentation fault package-query问题解决
  17. Excel 2010 VBA 入门 064 按照关键字批量创建超链接
  18. C# 使用 NPOI 处理Excel导入单元格内容是公式问题
  19. 《程序员修炼之道:从小工到专家》笔记-----第二章
  20. Vivado HLS常用优化命令介绍

热门文章

  1. caffe中的batchNorm层(caffe 中为什么bn层要和scale层一起使用)
  2. C#中Lambda表达式类型Expression不接受lambda函数
  3. Vsftpd文件传输服务(本地用户访问)
  4. Ubuntu 怎么增加根目录 大小
  5. 《程序员的修炼——从优秀到卓越》一一1.6 勿以专家自居
  6. android 开发中的常见问题
  7. logback常用配置
  8. Linux常用命令和服务器配置
  9. Linux下Socket 函数集(三)
  10. 安装SQL SERVER 2000时提示:以前的某个程序安装已在安装计算机上创建挂起的文件操作。...