Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 254|回复: 0

[Java基础知识]一个对象缓存池

[复制链接]
  • TA的每日心情
    开心
    2021-3-12 23:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-10-2 02:11:24 | 显示全部楼层 |阅读模式
    对象池(对象缓冲池)
    import java.util.*; /**
    * <p>Title: 对象缓冲池---采用最近、最久未使用策略管理对象,同时带有事件监听功能</p>
    *<p> 工作原理
    * <LI>采用集合框架(java.connection包)来实现最近最久未使用对象池</li>
    * <LI>首先构造对象池、设置池的大小</li>
    * <li>放置对象到池中,保存时候,池的指针指向该对象,以表明该对象最近最短被使用过</li>
    * <li>当把新的对象放入到池中时候,如果池已经满,那就删除最久没有被使用的对象,然后放入对象</li>
    * <li>从池中读取对象时,根据条件从池中获得对象;然后把池的指针指向该取出的对象,以表明该对象最近最短被使用过</li>
    * <li>当池中有对象被清除时候(当成垃圾清除),会触发相关事件
    * <li>当池被清空时候,会出发相关事件
    * </p>
    * <p>其他说明
    * 这个类参考了org.apache.tomcat.util.collections.LRUCache的实现细节。
    * 当然原代码采用Hashtable来存储池的对象列表,这里采用另外的存储方式---HashMap来存储
    * </p>
    * <p>Copyright: Copyright (c) 2004</p>
    * <p>Company: </p>
    *@see org.apache.tomcat.util.collections.LRUCache
    * <li> 文件位置jakarta-tomcat-5.5.6jakarta-tomcat-connectors\util
    * @author wdz123@hotmail.com
    * @version 1.0
    */ 代码一:
    1. import java.util.*;
    2. public class LRUCacheWithListener {

    3. /**
    4. * 池对象的包裹类,这样便于相关处理
    5. */
    6. class CacheNode {
    7.   CacheNode prev;
    8.   CacheNode next;
    9.   Abandon value;
    10.   Object key;
    11.   public CacheNode() {}
    12. }
    13. /**
    14. * 对象池大小
    15. **/
    16. private int cacheSize;

    17. /**
    18. * 对象列表、当然可以采用泛型编程,这样就实现自动装箱、解箱(boxing/unboxing)
    19. * **/
    20. private HashMap nodes;

    21. /**
    22. * 对象池当前对象数
    23. * **/
    24. private int currentSize;

    25. /**
    26. * 第一个节点
    27. * **/
    28. private CacheNode first;

    29. /***
    30. * 最后一个节点
    31. * **/
    32. private CacheNode last;
    33. private static int DEFAULT_SIZE = 10;

    34. public LRUCacheWithListener() {
    35.   this(DEFAULT_SIZE);
    36. }
    37. public LRUCacheWithListener(int poolSize) {
    38.   cacheSize = poolSize;
    39.   currentSize = 0;
    40.   first = null; //
    41.   last = null; //
    42.   nodes = new HashMap(poolSize);
    43. }

    44. /**
    45. * 读取一个对象
    46. * ***/
    47. public synchronized Object get(Object key) {
    48.   CacheNode node = (CacheNode) nodes.get(key);
    49.   if (node != null) {
    50.      moveToHead(node);
    51.      return node.value;
    52.   }else {
    53.    return null;
    54.   }
    55. }

    56. /**
    57. * 把指定对象移动到链表的头部
    58. * */
    59. private void moveToHead(CacheNode node) {
    60.    if (node == first) {
    61.        return;
    62.    }
    63.    if (node.prev != null) {
    64.      node.prev.next = node.next;
    65.    }
    66.    if (node.next != null) {
    67.      node.next.prev = node.prev;
    68.    }
    69.    if (last == node) {
    70.      last = node.prev;
    71.     }
    72.    if (first != null) {
    73.      node.next = first;
    74.      first.prev = node;
    75.    }
    76.    first = node;
    77.    node.prev = null;
    78.    if (last == null) {
    79.     last = first;
    80.    }
    81. }

    82. /**
    83. * 删除池中指定对象
    84. * **/
    85. public synchronized Object remove(Object key) {
    86.   CacheNode node = (CacheNode) nodes.get(key);
    87.   if (node != null) {
    88.    if (node.prev != null) {
    89.      node.prev.next = node.next;
    90.    }
    91.    if (node.next != null) {
    92.      node.next.prev = node.prev;
    93.    }
    94.    if (last == node) {
    95.      last = node.prev;
    96.    }
    97.    if (first == node) {
    98.      first = node.next;
    99.    }
    100. }
    101.   return node;
    102. }
    103. /****
    104. * 放置一个对象到池中
    105. * */
    106. public synchronized void put(Object key, Abandon value) {
    107. CacheNode node = (CacheNode) nodes.get(key);
    108. if (node == null) {
    109.   if (currentSize >= cacheSize) {//池满,删除最久没有使用的对象
    110.    if (last != null) {
    111.     nodes.remove(last.key);
    112.    }
    113.    removeLast();
    114.   }
    115.   else {//池没有满,直接把对象放入池中
    116.    currentSize++;
    117.   }
    118.   node = getANewCacheNode();
    119. }
    120. node.value = value;
    121. node.key = key;
    122. // 把放入池的这个对象移动到链表的头部,表示最近最短被使用过
    123. moveToHead(node);
    124. nodes.put(key, node);
    125. }

    126. /**清空池中对象
    127. * **/
    128. public synchronized void clear() {
    129. if (first!=null){
    130.   Iterator i= nodes.values().iterator();
    131.   //触发事件,该池已经被清空
    132.    CacheNode n;
    133.    while(i.hasNext()){
    134.    n = (CacheNode)(i.next());
    135.    n.value.poolClear();
    136. }
    137. }
    138. first = null;
    139. last = null;
    140. }
    141. /***
    142. * 获得一个新的包裹对象
    143. * **/
    144. private CacheNode getANewCacheNode(){
    145.   CacheNode node = new CacheNode();
    146.   return node;
    147. }
    148. /**
    149. * 删除池中最久没有使用的对象
    150. * **/
    151. private void removeLast() {
    152.   if (last != null) {
    153.    //对象从池中被抛弃,触发事件
    154.    last.value.onAbandon();
    155.    if (last.prev != null) {
    156.       last.prev.next = null;
    157.    }
    158.    else {
    159.     first = null;
    160.    }
    161.    last = last.prev;
    162.   }
    163. }
    164. }

    165. 代码二:
    166. /**
    167. * Title:
    168. *
    169. * Description: 定义对象被抛弃和池被清空的事件接口
    170. *
    171. * Copyright: Copyright (c) 2003
    172. *
    173. *@see org.apache.tomcat.util.collections.LRUCache
    174. * @author wdz123@hotmail.com
    175. * @version 1.0
    176. */
    177. public interface Abandon {
    178.   public void onAbandon();
    179.   public void poolClear();
    180. }

    181. 代码三:

    182. //测试部分
    183. /**
    184. * Title:
    185. *
    186. *Description: 测试使用带有事件回调机制的对象缓冲池---采用最近、最久未使用策略管理对象
    187. *
    188. * Copyright: Copyright (c) 2006
    189. *
    190. *@see org.apache.tomcat.util.collections.LRUCache
    191. * @author wdz123@hotmail.com
    192. * @version 1.0
    193. */

    194. public class CacheNodeWithListener implements Abandon {
    195.   int id;
    196.   public CacheNodeWithListener() {}
    197.   public CacheNodeWithListener(int i) {
    198.    id=i;
    199.   }
    200.   /**
    201.   * 当对象被池所抛弃时候,进行相关处理
    202.   * ***/
    203.   public void onAbandon(){
    204.    System.out.println(this+"---onAbandon()");
    205.   }
    206.   /**
    207.    * 当对象池被清空时候,进行相关处理
    208.    * ***/
    209.    public void poolClear(){
    210.       System.out.println(this+"---poolClear()");
    211.    }
    212.    public String toString(){
    213.      return "id="+id ;
    214.    }
    215.   static public void main(String [] s){
    216.     LRUCacheWithListener pool =new LRUCacheWithListener(3);
    217.     int i;
    218.     for (i=1;i<=5;i++) {
    219.       pool.put("obj"+i,new CacheNodeWithListener(i));
    220.     }
    221.     pool.clear();
    222.    }
    223. }
    224. 运行结果:
    225. C:java>javac   CacheNodeWithListener.java
    复制代码
    C:java>java CacheNodeWithListener
    id=1---onAbandon()
    id=2---onAbandon()
    id=3---poolClear()
    id=5---poolClear()
    id=4---poolClear()
      

      
      
       
       

         
       

         
       
      



    源码下载:http://file.javaxxz.com/2014/10/2/021124656.zip
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-5-20 04:39 , Processed in 0.387167 second(s), 46 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表