缓存主要为了解决各个组件之间读取速度不匹配问题,比如寄存器是L1的缓存,L1是L2的缓存,L2是L3的缓存,L3是内存的缓存等。通过读Java Concurrency Practice P85,实现了一个简单可以添加和获取数据的缓存。其它的诸如缓存过期,更新缓存等没有实现- -!!
代码
计算接口,用到了装饰者模式。
1 |
|
一种计算的实现
1 | public class ExpensiveFunction implements Computable<String,BigInteger> { |
版本1
通过HashMap时间复杂度为O(1)的特性以及synchronized保证线程安全来构建缓存
1 |
|
版本2
版本1添加了synchronized,多线程情况下造成性能下降 -> 换成ConcurrentHashMap
1 | public class MyCacheV2<A,V> implements Computable<A,V>{ |
版本3
版本2先判断 -> 在计算属于复合操作而且没有加锁导致线程不安全会产生重读计算。如果遇到计算时间非常长的计算,一旦重复会消耗大量的资源。
解决思路:如果其他线程正在计算目标值,当前线程阻塞直到其它线程计算出结果返回即可。
实现:通过FutureTask的get()方法。如果没有结果,会阻塞当前线程。
1 | public class MyCacheV3<A,V> implements Computable<A,V>{ |