首先guava LoadingCache的创建是基于Builder模式创建的,类似于一种函数是编程的方式,直接通过.方法名来完成LoadingCache的创建。如下:
private static LoadingCache<String,String> stringStringLoadingCache = CacheBuilder.newBuilder().initialCapacity(1000).maximumSize(10000). expireAfterAccess(12, TimeUnit.HOURS).build(new CacheLoader<String, String>() { @Override public String load(String s) throws Exception { return "null"; } });
guava的LoadingCache继承了Cache接口,里面定义了一些数据的存取的方法
loadingCache内部定义了静态类Segment<K,V>继承了重入锁,类似于concurrentHashMap的实现。
loadingCache的put ,get 都是基于Segment数组实现的实现的,如下:
final LocalCache.Segment<K, V>[] segments;
如下是put操作:
public V put(K key, V value) { Preconditions.checkNotNull(key); Preconditions.checkNotNull(value); int hash = this.hash(key); return this.segmentFor(hash).put(key, hash, value, false); }
首先检查key value是否为null ,之后根据key的hash值,定位应该在segment数组的那个位置
之后进行put操作,进入put之后,会使用重入锁的lock()方法来加锁,达到并发的目的,添加元素之前,会进行扩容的操作
会扩大为原来的两倍,阈值设置为新容量的3/4.
loadingCache内部有一个AtomicReferenceArray数组用来记录所有的key value键值对
在put时,首先根据key找到对应的segment数组的位置,之后使用hash(key)&table.length-1找到该segemnt所对应的entry数组的开头位置,然后开始向下遍历寻找,设置value值。
get操作与上述操作一致。