首页 > 编程知识 正文

loadrunner工作原理,数据库连接池原理

时间:2023-05-03 05:06:05 阅读:135007 作者:168

LruCache实现原理的分析最近研究了LruCahce的实现原理。 我以前也看过很多次源代码,但有些东西还没理解。 把代码重写了一遍,吼道。

的变量private final LinkedHashMapK,V map;/* * sizeofthiscacheinunits.notnecessarilythenumberofelements.*/private intsize; 私有最大; 私有输入计数; 私有int create count; private int evictionCount; 私有int hit count; 私有丢失计数; 映射:存储数据的集合size :当前LruCahce的内存占用maxSize:Lrucache的最大容量putCount:put的次数createCount:create的次数evictionCount :回收的次数LruCahce intmaxsize ) if ) maxsize=0) thrownewillegalargumentexception (' maxsize=0' ); } this.maxSize=maxSize; this.map=new LinkedHashMapK,v (0,0.75 f,true ); }现在,我们实例化了maxSize和LinkedHashMap对象,这是实现Lru算法的关键。 Lru是最近使用的算法的简称,表示要查找最近使用最少的对象。

代码new LinkedHashMapK,v (0,0.75 f,true )表示初始容量为零,0.75为加载因子,当达到最大容量的75%时将内存增加一半。 最后,这个参数很重要。 表示访问元素的排序方式,true表示按照访问顺序排序,false表示按照插入顺序排序。

在这里写了一个专门研究这两个参数差异的小程序。

如果设置为true :

publicstaticfinalvoidmain (string [ ] args ) { LinkedHashMapInteger,integer map=newlinkedhashmap (0,0.75 f,true ); map.put (0,0 ); map.put (1,1 ); map.put (2,2 ); map.put (3,3 ); map.put (4,4 ); map.put (5,5; map.put (6,6 ); map.get(1; map.get(2); 映射实体整数(for(map.entryinteger,integer entry :映射. entryset () system.out.println (entry.getkey ) ) ' 3360'entry } '输出结果

如果设置为033600336034336034360433604533605633606133601233602 false,则输出顺序为:

根据03360013360123360233603360336034336045336045336056336033606以上的结果,当将其设定为真时,如果对一个要素进行操作(put,get ),则将该要素置于集合的末尾

至此可知,该LinkedHashmap是实现Lru算法的中心,当内容容量达到最大值时,只要删除该集合的前面的要素直到集合的容量达到足以容纳数据的容量即可

那么,让我们来看看put方法吧。

publicfinalvput(kkey,V value ) if ) key==null||value==null ) thrownewnullpointerexception (' key==null|) v 同步(this ) { putCount; //put的次数1size=safesizeof(key,value ); //将当前容量增加到value大小previous=map.put(key,value )//previous为旧值if(previous!=null ) {

size -= safeSizeOf(key, previous); //如果旧的值不为空,就把旧的值得大小减去 } } if (previous != null) { entryRemoved(false, key, previous, value); } trimToSize(maxSize); return previous; }

由上面的代码可以看出来,首先把size增加,然后判断是否以前已经有元素,如果有,就更新当前的size,并且调用entryRemoved方法,entryRemoved是一个空实现,如果我们使用LruCache的时候需要掌握元素移除的信息,可以重写这个方法。最后就会调用trimToSize,来调整集合中的内容。

trimToSize 的实现如下:

public void trimToSize(int maxSize) { while (true) { K key; V value; synchronized (this) { if (size < 0 || (map.isEmpty() && size != 0)) { throw new IllegalStateException(getClass().getName() + ".sizeOf() is reporting inconsistent results!"); } if (size <= maxSize || map.isEmpty()) { break; } Map.Entry<K, V> toEvict = map.entrySet().iterator().next(); key = toEvict.getKey(); value = toEvict.getValue(); map.remove(key); size -= safeSizeOf(key, value); evictionCount++; } entryRemoved(true, key, value, null); } }

这个方法是一个无限循环,跳出循环的条件是,size < maxSize或者 map 为空。主要的功能是判断当前容量时候已经超出最大的容量,如果超出了maxSize的话,就会循环移除map中的第一个元素,直到达到跳出循环的条件。由上面的分析知道,map中的第一个元素就是最近最少使用的那个元素。

研究完了put方法之后,下面开始研究get方法。

public final V get(K key) { if (key == null) { throw new NullPointerException("key == null"); } V mapValue; synchronized (this) { mapValue = map.get(key); if (mapValue != null) { hitCount++; //命中 + 1 return mapValue; } missCount++;//丢失+1 } V createdValue = create(key); //创建 if (createdValue == null) { return null; } synchronized (this) { createCount++; //创建 + 1 mapValue = map.put(key, createdValue); if (mapValue != null) { // There was a conflict so undo that last put //如果有矛盾,意思就是有旧的值,就撤销put操作 map.put(key, mapValue); } else { size += safeSizeOf(key, createdValue); } } if (mapValue != null) { entryRemoved(false, key, createdValue, mapValue); return mapValue; } else { trimToSize(maxSize); return createdValue; } }

这个方法就先通过key来获取value,如果能获取到就就直接返回,获取不到的话,就调用create()方法创建一个,事实上,如果我们不重写这个create方法的话是return null的,所以整个流程就是获取得到就直接返回,获取不到就返回null。至于后面那段代码呢?我看了几遍也没理解是适合什么场景的。反正就是重写的create方法之后就会执行后面的代码,不过我们通常使用的时候都是没有重写这个方法的。

最后说一下remove方法:

public final V remove(K key) { if (key == null) { throw new NullPointerException("key == null"); } V previous; synchronized (this) { previous = map.remove(key); if (previous != null) { size -= safeSizeOf(key, previous); } } if (previous != null) { entryRemoved(false, key, previous, null); } return previous; }

remove方法没什么可以研究的了,就是使用remove方法移除一个元素。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。