java缓存 单例_架构师之jdk8-----------------ConcurrentHashMap快速构建本地缓存和单例模式...

本文展示了如何使用Java的ConcurrentHashMap作为本地缓存,以及如何结合单例模式来优化性能。通过比较普通计算、Java 7的同步缓存和Java 8的本地缓存实现,强调了ConcurrentHashMap在多线程环境下的高效性。同时,还给出了多线程并发操作ConcurrentHashMap的示例代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

import java.util.HashMap;

import java.util.HashSet;

import java.util.Map;

import java.util.concurrent.ConcurrentHashMap;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.TimeUnit;

public class Main {

static Map cache = new ConcurrentHashMap<>();

public static void main(String[] args) throws InterruptedException {

cache.put(0, 0);

cache.put(1, 1);

// 普通方式

System.out.println("Fibonacci(7) = " + fibonacci(7));

// 采用java7的同步线程方式及java8的本地缓存的方式

System.out.println("FibonacciJava8(7) = " + fibonacciJava8(7));

System.out.println("FibonacciJava7(7) = " + fibonacciJava7(7));

// 构建多值Map样例代码

Map> map1 = new HashMap<>();

map1.computeIfAbsent("fruits", k -> genValue(k)).add("apple");

map1.computeIfAbsent("fruits", k -> genValue(k)).add("orange");

map1.computeIfAbsent("fruits", k -> genValue(k)).add("pear");

map1.computeIfAbsent("fruits", k -> genValue(k)).add("banana");

map1.computeIfAbsent("fruits", k -> genValue(k)).add("water");

System.out.println(map1);

//测试多线程并发处理,是否同步操作

Map map2 = new ConcurrentHashMap<>();

ExecutorService exec = Executors.newCachedThreadPool();

for (int i = 0; i < 5; i++) {

exec.execute(() -> {

map2.computeIfAbsent("name", k -> genValue2(k));

map2.computeIfAbsent("addr", k -> genValue2(k));

map2.computeIfAbsent("email", k -> genValue2(k));

map2.computeIfAbsent("mobile", k -> genValue2(k));

});

}

exec.shutdown();

exec.awaitTermination(1, TimeUnit.SECONDS);

System.out.println(map2);

}

static HashSet genValue(String str) {

return new HashSet();

}

static String genValue2(String str) {

System.out.println("===");

return str + "2";

}

/**

* 普通的实现方式 普通方式使用大量的计算,存在性能问题. 并且计算量随着n的增加呈指数级增加,需要用到一些缓存策略,并且是线程安全的.

*

* @param n

* @return

*/

static int fibonacci(int n) {

if (n == 0 || n == 1)

return n;

System.out.println("calculating Fibonacci(" + n + ")");

return fibonacci(n - 2) + fibonacci(n - 1);

}

/**

* 采用java8的本地缓存方式 如果缓存MAP中不存在指定key的值,会自动调用mappingFunction(key)计算key的value

* 然后将key = value放入到缓存Map,java8会使用thread-safe的方式从cache中存取记录

*

* @param n

* @return

*/

static int fibonacciJava8(int n) {

return cache.computeIfAbsent(n, (key) -> {

System.out.println("calculating FibonacciJava8 " + n);

return fibonacciJava8(n - 2) + fibonacciJava8(n - 1);

});

}

/**

* 在java7中的实现方式

* 在java7中,通过synchronized进行线程同步,检查缓存是否存在key对应的值,如果不存在才进行计算并放入缓存中

* 为了更好的性能,需要使用 double-checked locking,那样代码会更复杂

*

* @param n

* @return

*/

static int fibonacciJava7(int n) {

if (n == 0 || n == 1)

return n;

Integer result = cache.get(n);

if (result == null) {

synchronized (cache) {

result = cache.get(n);

if (result == null) {

System.out.println("calculating FibonacciJava7(" + n + ")");

result = fibonacciJava7(n - 2) + fibonacciJava7(n - 1);

cache.put(n, result);

}

}

}

return result;

}

}

运行结果:

calculating Fibonacci(7)

calculating Fibonacci(5)

calculating Fibonacci(3)

calculating Fibonacci(2)

calculating Fibonacci(4)

calculating Fibonacci(2)

calculating Fibonacci(3)

calculating Fibonacci(2)

calculating Fibonacci(6)

calculating Fibonacci(4)

calculating Fibonacci(2)

calculating Fibonacci(3)

calculating Fibonacci(2)

calculating Fibonacci(5)

calculating Fibonacci(3)

calculating Fibonacci(2)

calculating Fibonacci(4)

calculating Fibonacci(2)

calculating Fibonacci(3)

calculating Fibonacci(2)

Fibonacci(7) = 13

calculating FibonacciJava8 7

calculating FibonacciJava8 5

calculating FibonacciJava8 3

calculating FibonacciJava8 2

calculating FibonacciJava8 4

calculating FibonacciJava8 6

FibonacciJava8(7) = 13

FibonacciJava7(7) = 13

{fruits=[orange, banana, apple, pear, water]}

===

===

===

===

{name=name2, mobile=mobile2, addr=addr2, email=email2}

分享到:

18e900b8666ce6f233d25ec02f95ee59.png

72dd548719f0ace4d5f9bca64e1d7715.png

2015-06-04 15:33

浏览 8286

评论

1 楼

bilimeng

2018-07-09

求教,ConcurrentHashMap不是线程安全的么,为啥还要加锁?不是多此一举吗??

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值