設計初衷:
網站在提供服務的過程中,會創建很多對象,bean,dao層的對象尤為頻繁,然而這些對象是可以重復利用的.
設計思路:
對象連接池ObjectPool才用單態的設計模式,自帶線程,每隔一段時間調用該類的
clearObject方法,
為了保證同步,涉及線程安全的方法全都使用了synchronized關鍵字
每個方法的流程控制根據存儲值會出現的狀態,以及會影響存儲值狀態的數據決定
要存儲進ObjectPool的類需要實現AllowEnterObjectPool接口
主要屬性介紹:
HashMap<String,ArrayList> hashMapForStorageObject,key是包名+類名,value存儲改類的實例,每次取出放回都會從0的位置
HashMap<String,Integer> hashMapForObjectUsedTime key是包名+類名+@+對象hashcode Integer記錄了對象被取出次數
主要方法介紹:
takeOut的方法利用泛型,只需傳給類的Class,便可返回對應類型,利用反射批量添加對象
put 是對象恢復到初始狀態(由程序員指定),放入到對應ArrayList的0位置
clearObject,由內部線程調用,遍歷hashMapForStorageObject每個ArrayList,如果ArrayList總數大於最小存儲數,再去
ashMapForObjectUsedTime查找使用記錄,將符合條件的對象刪除,最後清零使用記錄
代碼及使用方式:
package myFrame; public interface AllowEnterObjectPool { public ObjectPool objectPool = ObjectPool.getInstance(); //將對象放入改類時,需調用改方法,將對象恢復帶默認狀態 public void initialMember(); //當調用takeOut方法,發現沒有可用的對象使,會調用改方法批量加入 public void batchAddSelf(); }
package myFrame; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashSet; import com.sun.security.auth.NTDomainPrincipal; import Dao.TestDao; public class ObjectPool implements Debug,Assistant { //當只剩下30個對象的時候,就不進行刪除行為了 private int minNumber = 30; //每隔多少時間進行檢查 private int checkTime = 60*60*1000; //每個類對應一個ArrayList // key值已包名+類名的方式 // value值是存儲該對象的Arraylist // value影響程序流程的值 null(沒有找到key) 0(size) // 影響value的狀態的值 minNumber private HashMap<String,ArrayList> hashMapForStorageObject = new HashMap<String, ArrayList>(); //每個對象對應一個Integer,記錄一段時間內被調用得次數 /* * key值已包名+類名+@+對象hashcode value 記錄了該對象被取出的次數 value影響程序流程的值 null(沒有找到key) >0(被使用過) */ private HashMap<String,Integer> hashMapForObjectUsedTime = new HashMap<String, Integer>(); private static ObjectPool objectPool = new ObjectPool(); private ObjectPool() { new clock().start(); } //得到一個類的實例,每次都從0獲取,並從ArrayList中刪除 public<T> T takeOut(Class<T> object) { synchronized (this) { String className = object.getName(); ArrayList<T> objectList = hashMapForStorageObject.get(className); if(objectList == null) { objectList = new ArrayList<T>(); hashMapForStorageObject.put(className,objectList); T createObject = null; try { createObject = object.newInstance(); Method batchAddSelf = object.getMethod("batchAddSelf"); batchAddSelf.invoke(createObject); objectList.add(createObject); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } else if(objectList.size()==0) { T createObject = null; try { createObject = object.newInstance(); Method batchAddSelf = object.getMethod("batchAddSelf"); batchAddSelf.invoke(createObject); objectList.add(createObject); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } T returnObject = objectList.get(0); String flag = className+"@"+Integer.toHexString(returnObject.hashCode()); Integer i = hashMapForObjectUsedTime.get(flag); if(i == null) { i = 0; } hashMapForObjectUsedTime.put(flag,++i); objectList.remove(returnObject); return returnObject; } } /* * 將對象恢復到初始狀態後,放入0位置 */ public synchronized void put(AllowEnterObjectPool allowEnterObjectPool) { allowEnterObjectPool.initialMember(); String className = allowEnterObjectPool.getClass().getName(); ArrayList objectList = hashMapForStorageObject.get(className); if(objectList == null) { objectList = new ArrayList(); hashMapForStorageObject.put(className,objectList); } objectList.add(0,allowEnterObjectPool); } /* * 已hashMapForStorageObject為准,取出一個ArrayList A,遍歷裡面的對象,例如對a ,組成hashMapForObjectUsedTime的key值 * 當A的容量大於minnumber時,則通過key查找hashMapForObjectUsedTime,得到value為null的話,則刪除A裡面的對應對象 * 將hashMapForObjectUsedTime數據清除 */ public synchronized void clearObject() { Iterator<String> iterator = hashMapForStorageObject.keySet().iterator(); String key,flag; ArrayList list; while (iterator.hasNext()) { key = iterator.next(); list = hashMapForStorageObject.get(key); Object object; Integer usedTime; if (list.size()<minNumber) { continue; } for(int i=0;i<list.size();i++) { object = list.get(i); flag = key+"@"+Integer.toHexString(object.hashCode()); usedTime = hashMapForObjectUsedTime.get(flag); if(usedTime == null) { list.remove(i); hashMapForObjectUsedTime.remove(key); i--; if(list.size() == minNumber) break; } } } hashMapForObjectUsedTime.clear(); } public static ObjectPool getInstance() { return objectPool; } private class clock extends Thread { @Override public void run() { System.out.println("時鐘啟動"); while(true) { try { Thread.sleep(checkTime); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } clearObject(); } } } public static void main(String[] args) { Message message = objectPool.takeOut(Message.class); objectPool.put(message); System.out.println(message); } }
package myFrame; public class Message implements AllowEnterObjectPool { private String name; private int age; public Message() { } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public void initialMember() { // TODO Auto-generated method stub name = ""; age = 0; } @Override public void batchAddSelf() { Message message; for(int i=0;i<10;i++) { message = new Message(); objectPool.put(message); } } }