設計初衷:
網站在提供服務的過程中,會創建很多對象,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);
}
}
}