admin 管理员组文章数量: 887021
2024年1月16日发(作者:gzip在线压缩)
JAVA缓存
1 Cache类
2 CacheManager类
JAVA缓存有两种:
一、文件缓存,是指把数据存储在磁盘上,可以XML格式,也可以序列化文件DAT格式还是其它文件格式。
二、内存缓存,也就是实现一个类中静态Map,对这个Map进行常规的增删查。
其代码如下:
JAVA缓存 - Cache类
public class Cache {
private String key;//缓存ID
private Object value;//缓存数据
private long timeOut;//更新时间
private boolean expired; //是否终止
public Cache() {
super();
}
public Cache(String key, Object value, long timeOut, boolean expired) {
= key;
= value;
t = timeOut;
d = expired;
}
public String getKey() {
return key;
}
public long getTimeOut() {
return timeOut;
}
public Object getValue() {
return value;
}
public void setKey(String string) {
key = string;
}
public void setTimeOut(long l) {
timeOut = l;
}
public void setValue(Object object) {
value = object;
}
public booleanisExpired() {
return expired;
}
public void setExpired(boolean b) {
expired = b;
}
}
//测试类,
class Test {
public static void main(String[] args) {
n(pleFlag("alksd"));
// he("abc", new Cache());
// he("def", new Cache());
// he("ccc", new Cache());
// nly("");
// Cache c = new Cache();
// for (int i = 0; i < 10; i++) {
// he("" + i, c);
// }
// he("aaaaaaaa", c);
// he("abchcy;alskd", c);
// he("cccccccc", c);
// he("abcoqiwhcy", c);
// n("删除前的大小:"+heSize());
// heAllkey();
// ll("aaaa");
// n("删除后的大小:"+heSize());
// heAllkey();
}
}
JAVA缓存 - CacheManager类
public class CacheManager {
private static HashMapcacheMap = new HashMap();
//单实例构造方法
private CacheManager() {
super();
}
//获取布尔值的缓存
public static booleangetSimpleFlag(String key){
try{
return (Boolean) (key);
}catch(NullPointerException e){
return false;
}
}
public static long getServerStartdt(String key){
try {
return (Long)(key);
} catch (Exception ex) {
return 0;
}
}
//设置布尔值的缓存
public synchronized static booleansetSimpleFlag(String key,boolean flag){
if (flag &&getSimpleFlag(key)) {//假如为真不允许被覆盖
return false;
}else{
(key, flag);
return true;
}
}
public synchronized static booleansetSimpleFlag(String key,longserverbegrundt){
if ((key) == null) {
(key,serverbegrundt);
return true;
}else{
return false;
}
}
//得到缓存。同步静态方法
private synchronized static Cache getCache(String key) {
return (Cache) (key);
}
//判断是否存在一个缓存
private synchronized static booleanhasCache(String key) {
return nsKey(key);
}
//清除所有缓存
public synchronized static void clearAll() {
();
}
//清除某一类特定缓存,通过遍历HASHMAP下的所有对象,来判断它的KEY与传入的TYPE是否匹配
public synchronized static void clearAll(String type) {
Iterator i = et().iterator();
String key;
ArrayListarr = new ArrayList();
try {
while (t()) {
entry = () ();
key = (String) ();
if (With(type)) { //如果匹配则删除掉
(key);
}
}
for (int k = 0; k <(); k++) {
clearOnly((k));
}
} catch (Exception ex) {
tackTrace();
}
}
//清除指定的缓存
public synchronized static void clearOnly(String key) {
(key);
}
//载入缓存
public synchronized static void putCache(String key, Cache obj) {
(key, obj);
}
//获取缓存信息
public static Cache getCacheInfo(String key) {
if (hasCache(key)) {
Cache cache = getCache(key);
if (cacheExpired(cache)) { //调用判断是否终止方法
ired(true);
}
return cache;
}else
return null;
}
//载入缓存信息
public static void putCacheInfo(String key, Cache obj, long dt,boolean expired) {
Cache cache = new Cache();
(key);
eOut(dt + tTimeMillis()); //设置多久后更新缓存
ue(obj);
ired(expired); //缓存默认载入时,终止状态为FALSE
(key, cache);
}
//重写载入缓存信息方法
public static void putCacheInfo(String key,Cacheobj,longdt){
Cache cache = new Cache();
(key);
eOut(dt+tTimeMillis());
ue(obj);
ired(false);
(key,cache);
}
//判断缓存是否终止
public static booleancacheExpired(Cache cache) {
if (null == cache) { //传入的缓存不存在
return false;
}
long nowDt = tTimeMillis(); //系统当前的毫秒数
long cacheDt = eOut(); //缓存内的过期毫秒数
if (cacheDt<= 0||cacheDt>nowDt) { //过期时间小于等于零时,或者过期时间大于当前时间时,则为FALSE
return false;
} else { //大于过期时间 即过期
return true;
}
}
//获取缓存中的大小
public static intgetCacheSize() {
return ();
}
//获取指定的类型的大小
public static intgetCacheSize(String type) {
int k = 0;
Iterator i = et().iterator();
String key;
try {
while (t()) {
entry = () ();
key = (String) ();
if (f(type) != -1) { //如果匹配则删除掉
k++;
}
}
} catch (Exception ex) {
tackTrace();
}
return k;
}
//获取缓存对象中的所有键值名称
public static ArrayListgetCacheAllkey() {
ArrayList a = new ArrayList();
try {
Iterator i = et().iterator();
while (t()) {
entry = () ();
((String) ());
}
} catch (Exception ex) {} finally {
return a;
}
}
//获取缓存对象中指定类型 的键值名称
public static ArrayListgetCacheListkey(String type) {
ArrayList a = new ArrayList();
String key;
try {
Iterator i = et().iterator();
while (t()) {
entry = () ();
key = (String) ();
if (f(type) != -1) {
(key);
}
}
} catch (Exception ex) {} finally {
return a;
}
}
}
2007-09-29
简单LRU算法实现缓存
最简单的LRU算法实现,就是利用jdk的LinkedHashMap,removeEldestEntry()方法即可,如下所示:
java 代码
1. import ist;
覆写其中的
2.
3.
4.
5.
6.
7.
8.
9.
import tion;
import HashMap;
import ;
import antLock;
import ;
/**
10. * 类说明:利用LinkedHashMap实现简单的缓存, 必须实现removeEldestEntry方法,具体参见JDK文档
11. *
12. * @author dennis
13. *
14. * @param
15. * @param
16. */
17. public class LRULinkedHashMap
18. private final int maxCapacity;
19.
20. private static final float DEFAULT_LOAD_FACTOR = 0.75f;
21.
22. private final Lock lock = new ReentrantLock();
23.
24. public LRULinkedHashMap(int maxCapacity) {
25. super(maxCapacity, DEFAULT_LOAD_FACTOR, true);
26. acity = maxCapacity;
27. }
28.
29. @Override
30. protected boolean removeEldestEntry(
31. return size() > maxCapacity;
32. }
33. @Override
34. public boolean containsKey(Object key) {
35. try {
36. ();
37. return nsKey(key);
38. } finally {
39. ();
40. }
41. }
42.
43.
44. @Override
45. public V get(Object key) {
46. try {
47. ();
48. return (key);
49. } finally {
50. ();
51. }
52. }
53.
54. @Override
55. public V put(K key, V value) {
56. try {
57. ();
58. return (key, value);
59. } finally {
60. ();
61. }
62. }
63.
64. public int size() {
65. try {
66. ();
67. return ();
68. } finally {
69. ();
70. }
71. }
72.
73. public void clear() {
74. try {
75. ();
76. ();
77. } finally {
78. ();
79. }
80. }
81.
82. public Collection<
83. try {
84. ();
85. return new ArrayList<
86. } finally {
87. ();
88. }
89. }
90. }
91.
如果你去看LinkedHashMap的源码可知,LRU算法是通过双向链表来实现,当某个位置被命中,通过调整链表的指向将该位置调整到头位置,新加入的内容直接放在链表头,如此一来,最近被命中的内容就向链表头移动,需要替换时,链表最后的位置就是最近最少使用的位置。
LRU算法还可以通过计数来实现,缓存存储的位置附带一个计数器,当命中时将计数器加1,替换时就查找计数最小的位置并替换,结合访问时间戳来实现。这种算法比较适合缓存数据量较小的场景,显然,遍历查找计数最小位置的时间复杂度为O(n)。我实现了一个,结合了访问时间戳,当最小计数大于 MINI_ACESS时,就移除最久没有被访问的项:
java 代码
1. import izable;
2. import ist;
3. import tion;
4. import p;
5. import or;
6. import ;
7. import ;
8. import Integer;
9. import Long;
10. import ;
11. import antLock;
12.
13. /**
14. *
15. * @author dennis
16. * 类说明:当缓存数目不多时,才用缓存计数的传统LRU算法
17. * @param
18. * @param
19. */
20. public class LRUCache
21.
22. private static final int DEFAULT_CAPACITY = 100;
23.
24. protected Map
25.
26. private final Lock lock = new ReentrantLock();
27.
28. private final transient int maxCapacity;
29.
30. private static int MINI_ACCESS = 10;
31.
32. public LRUCache() {
33. this(DEFAULT_CAPACITY);
34. }
35.
36. public LRUCache(int capacity) {
37. if (capacity <= 0)
38. throw new RuntimeException("缓存容量不得小于0");
39. acity = capacity;
40. = new HashMap
41. }
42.
43. public boolean ContainsKey(K key) {
44. try {
45. ();
46. return nsKey(key);
47. } finally {
48. ();
49. }
50. }
51.
52. public V put(K key, V value) {
53. try {
54. ();
55. if ((() > maxCapacity - 1) && !nsKey(key)) {
56. // n("开始");
57. Set<
58. removeRencentlyLeastAccess(entries);
59. }
60. ValueEntry valueEntry = (key, new ValueEntry(value));
61. if (valueEntry != null)
62. return ;
63. else
64. return null;
65. } finally {
66. ();
67. }
68. }
69.
70. /**
71. * 移除最近最少访问
72. */
73. protected void removeRencentlyLeastAccess(
74. Set<
75. // 最小使用次数
76. int least = 0;
77. // 最久没有被访问
78. long earliest = 0;
79. K toBeRemovedByCount = null;
80. K toBeRemovedByTime = null;
81. Iterator<
82. if (t()) {
83.
84. least = ue().();
85. toBeRemovedByCount = ();
86. earliest = ue().();
87. toBeRemovedByTime = ();
88. }
89. while (t()) {
90.
91. if (ue().() < least) {
92. least = ue().();
93. toBeRemovedByCount = ();
94. }
95. if (ue().() < earliest) {
96. earliest = ue().();
97. toBeRemovedByTime = ();
98. }
99. }
100. // n("remove:" + toBeRemoved);
101. // 如果最少使用次数大于MINI_ACCESS,那么移除访问时间最早的项(也就是最久没有被访问的项)
102. if (least > MINI_ACCESS) {
103. (toBeRemovedByTime);
104. } else {
105. (toBeRemovedByCount);
106. }
107. }
108.
109. public V get(K key) {
110. try {
111. ();
112. V value = null;
113. ValueEntry valueEntry = (key);
114. if (valueEntry != null) {
115. // 更新访问时间戳
116. LastAccess();
117. // 更新访问次数
118. entAndGet();
119. value = ;
120. }
121. return value;
122. } finally {
123. ();
124. }
125. }
126.
127. public void clear() {
128. try {
129. ();
130. ();
131. } finally {
132. ();
133. }
134. }
135.
136. public int size() {
137. try {
138. ();
139. return ();
140. } finally {
141. ();
142. }
143. }
144.
145. public Collection<
146. try {
147. ();
148. Set
149. Map
150. for (K key : keys) {
151. (key, (key).value);
152. }
153. return new ArrayList<
154. } finally {
155. ();
156. }
157. }
158.
159. class ValueEntry implements Serializable {
160. private V value;
161.
162. private AtomicInteger count;
163.
164. private AtomicLong lastAccess;
165.
166. public ValueEntry(V value) {
167. = value;
168. = new AtomicInteger(0);
169. lastAccess = new AtomicLong(me());
170. }
171.
172. public void updateLastAccess() {
173. (me());
174. }
175.
176. }
177. }
2008-04-07
LRU Cache
看了下RU(Least Recently Used ,最近最少使用),可以使用LinkedHashMap实现,到是蛮简单的.LinkedHashMap会将get或是put的数据置于底端.
重写removeEldestEntry()可以设定根据size来调整cache的数量.
Java代码
1. import tion;
2. import HashMap;
3. import ;
4.
5. /**
6. * This class uses the LinkedHashMap to build LRU cache.
7. * User can define the cache size.
8. */
9. public class LRUCache
10. {
11. int cacheSize = 0;
12. float loadFactor = 0.75f; //default
13. LinkedHashMap map;
14.
15. public LRUCache(int cacheSize)
16. {
17. ize = cacheSize;
18. map = new LinkedHashMap(cacheSize, loadFactor, true)
19. {
20. protected boolean removeEldestEntry( eldest)
21. {
22. return size() > ize;
23. //return false;
24. }
25. };
26. }
27.
28. public synchronized void clear()
29. {
30. ();
31. }
32.
33. public synchronized Object get(Object key)
34. {
35. return (key);
36. }
37.
38. public synchronized void put(Object key, Object value)
39. {
40. (
41. key,
42. value);
43. }
44.
45. public synchronized Object remove(Object key)
46. {
47. return (key);
48. }
49.
50. public synchronized int size()
51. {
52. return ();
53. }
54.
55. public synchronized Collection values()
56. {
57. return ();
58. }
59.
60. public static void main(String []args)
61. {
62. // testing
63. int size = 3;
64. LRUCache cache = new LRUCache(size);
65. (new Integer("1"), "1");
66. (new Integer("2"), "2");
67. (new Integer("3"), "3");
68.
69. String value = (String)(new Integer(1));
70. n(value);
71. n("Testing ...");
72.
73. Object[] values = ().toArray();
74. for (int i = 0; i < ; i++)
75. {
76. value = (String)values[i];
77. n(value);
78. }
79. }
80. }
LRU缓存应用一例
首先,来看看LRU的定义: Least recently used. 可以理解为,最少使用的被淘汰。在网上发现了这个LRUCache 类及文章
《基于双链表实现缓存策略之LRU实现》,正好站内有一个搜索
《ACM AND JAVA》/cwbwebhome/
需要缓存,应用了一把,这样就不需要每次搜索POJID都查询数据库。先凑合着用了。
package ;
import ble;
.*;
public class LRUCache {
private intcacheSize;
private Hashtable nodes;//缓存容器
private intcurrentSize;
private CacheNode first;//链表头
private CacheNode last;//链表尾
private static LRUCache instance=new LRUCache(1000);
/**
* 链表节点
* @author Administrator
*
*/
class CacheNode {
CacheNodeprev;//前一节点
CacheNode next;//后一节点
Object value;//值
Object key;//键
CacheNode() {
}
}
private LRUCache(int i) {
currentSize = 0;
cacheSize = i;
nodes = new Hashtable(i);//缓存容器
ResultSetRst=null;
DbTransdb=new DbTrans();
try{
Rst=eQuery("select File_name,Article_type from Article where type_id=17");
String f_name=null;
String a_type=null;
while(()){//将数据库中的记录全部取出,缓存。
a_type=ing("Article_type");
f_name=ing("File_name");
put(a_type,f_name);
}
if(Rst!=null) ();
if(db!=null) ();
}catch(SQLException e){
n(ng());
}
}
public static LRUCachegetInstance(){
return instance;
}
/**
* 获取缓存中对象
* @param key
* @return
*/
public Object get(Object key) {
CacheNode node = (CacheNode) (key);
if (node != null) {
moveToHead(node);
return ;
} else {
return null;
}
}
/**
* 添加缓存
* @param key
* @param value
*/
public void put(Object key, Object value) {
CacheNode node = (CacheNode) (key);
if (node == null) {
//缓存容器是否已经超过大小.
if (currentSize>= cacheSize) {
if (last != null)//将最少使用的删除
();
removeLast();
} else {
currentSize++;
}
node = new CacheNode();
}
= value;
= key;
//将最新使用的节点放到链表头,表示最新使用的.
moveToHead(node);
(key, node);
}
/**
* 将缓存删除
* @param key
* @return
*/
public Object remove(Object key) {
CacheNode node = (CacheNode) (key);
if (node != null) {
if ( != null) {
= ;
}
if ( != null) {
= ;
}
if (last == node)
last = ;
if (first == node)
first = ;
}
return node;
}
public void clear() {
first = null;
last = null;
}
/**
* 删除链表尾部节点
* 表示 删除最少使用的缓存对象
*/
private void removeLast() {
//链表尾不为空,则将链表尾指向null. 删除连表尾(删除最少使用的缓存对象)
if (last != null) {
if ( != null)
= null;
else
first = null;
last = ;
}
}
/**
* 移动到链表头,表示这个节点是最新使用过的
* @param node
*/
private void moveToHead(CacheNode node) {
if (node == first)
return;
if ( != null)
= ;
if ( != null)
= ;
if (last == node)
last = ;
if (first != null) {
= first;
= node;
}
first = node;
= null;
if (last == null)
last = first;
}
}
有些不满意之处,主要是缓存大小不好确定,暂定为1000, 以后题目多了,要重新编译源文件。(缓存大小最好写在一个配置
文件中)
最后看一下JSP文件:,从提交页面获取POJID,从缓存中取数据。
<%@ page import="he" %>
<%@ page import="r" %>
<%@ page import="n" %>
<%@ page import="he" %>
<%
String s=ameter("s");
String toPage="";
String pattern = "d{1,5}";
n(s);
if(s==null||()==0) {
toPage="";
}else {
Pattern p = e(pattern);
Matcher m = r(s);
boolean b = s();
n(b);
if(!b){
toPage="";
}else{
LRUCache cache=tance();
String f_name=(String)(s);
if(f_name!=null)
toPage=f_name;
else
toPage="";
}
}
direct(toPage);
%>
版权声明:本文标题:java缓存 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.freenas.com.cn/free/1705402950h483527.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论