paulwong

          對象池

          如果一個B/S的應用,并發量在2000以上時,新建的對象累積會占用大量內存,當超過一定數量的時候,會報內存不夠,使用享元模式就可以解決這一問題,也就是建立對象池?,F在的方案可以使用Apache Commons Pool

          一、基本String對象測試
          import org.apache.commons.pool.impl.GenericKeyedObjectPool; 
          import org.apache.commons.pool.BaseKeyedPoolableObjectFactory; 

          /** 
          * Created by IntelliJ IDEA. 

          @author leizhimin 2009-10-27 17:46:18 
          */
           
          public class Test 
                  
          public static void main(String[] args) throws Exception 
                          
          //創建一個對象池 
                          GenericKeyedObjectPool pool = new GenericKeyedObjectPool(new BaseKeyedPoolableObjectFactory() 
                                  @Override 
                                  
          public Object makeObject(Object o) throws Exception 
                                          
          return o; 
                                  }
           
                          }
          ); 

                          
          //添加對象到池,重復的不會重復入池 
                          pool.addObject("a"); 
                          pool.addObject(
          "a"); 
                          pool.addObject(
          "b"); 
                          pool.addObject(
          "x"); 

                          
          //清除最早的對象 
                          pool.clearOldest(); 

                          
          //獲取并輸出對象 
                          System.out.println(pool.borrowObject("a")); 
                          System.out.println(pool.borrowObject(
          "b")); 
                          System.out.println(pool.borrowObject(
          "c")); 
                          System.out.println(pool.borrowObject(
          "c")); 
                          System.out.println(pool.borrowObject(
          "a")); 

                          
          //輸出池狀態 
                          System.out.println(pool.getMaxIdle()); 
                          System.out.println(pool.getMaxActive()); 

                  }
           
          }

          輸出結果:
          a
          b
          c
          c
          a
          8
          8

          Process finished with exit code 0

          二、自定義復雜對象測試

          import org.apache.commons.pool.impl.GenericKeyedObjectPool; 
          import org.apache.commons.pool.BaseKeyedPoolableObjectFactory; 

          /** 
          * Created by IntelliJ IDEA. 

          @author leizhimin 2009-10-27 17:46:18 
          */
           
          public class Test 
                  
          public static void main(String[] args) throws Exception 
                          
          //創建一個對象池 
                          GenericKeyedObjectPool pool = new GenericKeyedObjectPool(new BaseKeyedPoolableObjectFactory() 
                                  @Override 
                                  
          public Object makeObject(Object o) throws Exception 
                                          
          if (o != null && o instanceof User) 
                                                  
          return o; 
                                          
          else 
                                                  
          return null
                                  }
           
                          }
          ); 

                          
          //添加對象到池,重復的不會重復入池 
                          pool.addObject("a"); 
                          pool.addObject(
          "b"); 
                          pool.addObject(
          "x"); 
                          pool.addObject(
          null); 
                          pool.addObject(
          null); 
                          pool.addObject(
          null); 
                          pool.addObject(
          new User("zhangsan""123")); 
                          pool.addObject(
          new User("lisi""112")); 
                          pool.addObject(
          new User("lisi""112"32)); 
                          pool.addObject(
          new User("lisi""112"32"一個爛人!")); 


                          
          //清除最早的對象 
                          pool.clearOldest(); 

                          
          //獲取并輸出對象 
                          User u1 = new User("lisi""112"32"一個爛人!"); 
                          System.out.println(pool.borrowObject(u1)); 
                          pool.returnObject(u1,u1); 

                          
          //獲取并輸出對象 
                          User u2 = new User("lisi""112"32"一個爛人!"); 
                          System.out.println(pool.borrowObject(u2)); 
                          pool.returnObject(u2,u2); 

                          
          //獲取并輸出對象 
                          User u3 = new User("lisi""112"32); 
                          System.out.println(pool.borrowObject(u3)); 
                          pool.returnObject(u3,u3); 

                          
          //獲取并輸出對象 
                          User u4 = new User("lisi""112"); 
                          System.out.println(pool.borrowObject(u4)); 
                          pool.returnObject(u4,u4); 

                          System.out.println(pool.borrowObject(u4)); 
                          pool.returnObject(u4,u4); 
                          System.out.println(pool.borrowObject(u4)); 
                          pool.returnObject(u4,u4); 
                          System.out.println(pool.borrowObject(u4)); 
                          pool.returnObject(u4,u4); 
                          System.out.println(pool.borrowObject(u4)); 
                          pool.returnObject(u4,u4); 
                          System.out.println(pool.borrowObject(u4)); 
                          pool.returnObject(u4,u4); 
                          System.out.println(pool.borrowObject(u4)); 
                          pool.returnObject(u4,u4); 
                          System.out.println(pool.borrowObject(u4)); 
                          pool.returnObject(u4,u4); 





                          System.out.println(pool.borrowObject(
          new User("lisi""112"))); 
          //                System.out.println(pool.borrowObject(new User("lisi", "112"))); 

                          
          //輸出池狀態 
                          System.out.println(pool.getMaxIdle()); 
                          System.out.println(pool.getMaxActive()); 
                          pool.clearOldest(); 
                          pool.close(); 

                  }
           
          }
           

          class User 
                  
          private String name; 
                  
          private String pswd; 
                  
          private int age; 
                  
          private String reamark; 

                  User() 

                  }
           

                  User(String name, String pswd) 

                          
          this.name = name; 
                          
          this.pswd = pswd; 
                  }
           

                  User(String name, String pswd, 
          int age) 
                          
          this.name = name; 
                          
          this.pswd = pswd; 
                          
          this.age = age; 
                  }
           

                  User(String name, String pswd, 
          int age, String reamark) 
                          
          this.name = name; 
                          
          this.pswd = pswd; 
                          
          this.age = age; 
                          
          this.reamark = reamark; 
                  }
           

                  
          public String getName() 
                          
          return name; 
                  }
           

                  
          public void setName(String name) 
                          
          this.name = name; 
                  }
           

                  
          public String getPswd() 
                          
          return pswd; 
                  }
           

                  
          public void setPswd(String pswd) 
                          
          this.pswd = pswd; 
                  }
           

                  
          public int getAge() 
                          
          return age; 
                  }
           

                  
          public void setAge(int age) 
                          
          this.age = age; 
                  }
           

                  
          public String getReamark() 
                          
          return reamark; 
                  }
           

                  
          public void setReamark(String reamark) 
                          
          this.reamark = reamark; 
                  }
           

                  @Override 
                  
          public boolean equals(Object o) 
                          
          if (this == o) return true
                          
          if (o == null || getClass() != o.getClass()) return false

                          User user 
          = (User) o; 

                          
          if (!name.equals(user.name)) return false
                          
          if (!pswd.equals(user.pswd)) return false

                          
          return true
                  }
           

                  @Override 
                  
          public int hashCode() 
                          
          int result = name.hashCode(); 
                          result 
          = 31 * result + pswd.hashCode(); 
                          
          return result; 
                  }
           

                  @Override 
                  
          public String toString() 
                          
          return "User{" + 
                                          
          "name='" + name + '\'' + 
                       
                             
          ", pswd='" + pswd + '\'' + 
                                          ", age=" + age + 
                                          
          ", reamark='" + reamark + '\'' + 
                                          '}'
                  }
           
          }

          測試結果:
          User{name='lisi', pswd='112', age=32, reamark='null'}
          User{name='lisi', pswd='112', age=32, reamark='一個爛人!'}
          User{name='lisi', pswd='112', age=32, reamark='一個爛人!'}
          User{name='lisi', pswd='112', age=32, reamark='null'}
          User{name='lisi', pswd='112', age=0, reamark='null'}
          User{name='lisi', pswd='112', age=0, reamark='null'}
          User{name='lisi', pswd='112', age=0, reamark='null'}
          User{name='lisi', pswd='112', age=0, reamark='null'}
          User{name='lisi', pswd='112', age=0, reamark='null'}
          User{name='lisi', pswd='112', age=0, reamark='null'}
          User{name='lisi', pswd='112', age=0, reamark='null'}
          User{name='lisi', pswd='112', age=0, reamark='null'}
          8
          8

          Process finished with exit code 0

          這次測試得出一些有用的結論:
          1、復雜對象應該實現equals() 、hashCode()方法,以便不重復入池。
          2、對于非入池的目標對象,比如a、b、x字符串,目前沒有有效的辦法過濾掉,不讓其入池,雖然在工廠方法里做了努力。
          3、試圖將null入池,不會成功的,但也不拋異常。
          4、對于池對象,使用應該遵循“接而有還,再借不難”-----從池中獲取,不用時候歸池,否則當池中沒有空閑可用的對象時候,程序會處于等待狀態,如果沒有顯式的調用歸還方法,則造成程序死鎖。

          池的大小是初始化配置的,在沒有顯式配置指定的情況下,池大小默認為8.可以通過GenericKeyedObjectPool.Config來配置。

          posted on 2011-10-23 17:02 paulwong 閱讀(352) 評論(0)  編輯  收藏 所屬分類: 性能優化

          主站蜘蛛池模板: 湟源县| 垣曲县| 芜湖市| 吴堡县| 横山县| 九台市| 淳化县| 宣化县| 建始县| 基隆市| 铁岭市| 固镇县| 尉氏县| 巴东县| 洛宁县| 遂平县| 南江县| 凤庆县| 永川市| 瑞金市| 霍州市| 秦安县| 太康县| 中方县| 阳原县| 天等县| 华安县| 泽普县| 孟津县| 玉田县| 株洲市| 米泉市| 准格尔旗| 建水县| 古交市| 临邑县| 资兴市| 饶平县| 富川| 民勤县| 澄城县|