舉例講解Java設(shè)計(jì)模式中的對象池模式編程
定義
一個(gè)對象池是一組已經(jīng)初始化過且可以使用的對象的集合,池的用戶可以從池子中取得對象,對其進(jìn)行操作處理,并在不需要時(shí)歸還給池子而非銷毀它。
若初始化、實(shí)例化的代價(jià)高,且有需求需要經(jīng)常實(shí)例化,但每次實(shí)例化的數(shù)量較少的情況下,使用對象池可以獲得顯著的效能提升。從池子中取得對象的時(shí)間是可預(yù)測的,但新建一個(gè)實(shí)例所需的時(shí)間是不確定。
實(shí)現(xiàn)

1. Reusable - 對象池中的對象,通常實(shí)例化代價(jià)比較高。
2. Client - 使用一個(gè)對象的實(shí)例。
3. ReusablePool - 管理對象的實(shí)例化,回收和銷毀。
單個(gè)實(shí)例中主要的思想
1.一個(gè)棧,這里用stack
2.初始化方法,容器開啟的時(shí)候可以預(yù)先創(chuàng)建池
3.創(chuàng)建實(shí)例的方法
4.提供從池中獲得對象實(shí)例的方法
5.提供返回的方法,不返回后果很嚴(yán)重
6.控制請求等待時(shí)間的方法,過了一定的事件還沒獲得對象實(shí)例,就返回一個(gè)null指針
import java.util.Stack;
@SuppressWarnings("unchecked")
public class ObjectPool {
public ObjectPool() {
}
private PoolParam poolParam;
public void setPoolParam(PoolParam poolParam) {
this.poolParam = poolParam;
}
// 當(dāng)前總對象個(gè)數(shù)
private int currentNum = 0;
private Class clazz;
public void setClazz(Class clazz) {
this.clazz = clazz;
}
// 棧,用來存放對象,模擬一個(gè)池
private Stack stack;
public Stack getStack() {
return stack;
}
public void setStack(Stack stack) {
this.stack = stack;
}
// .................................................................
// 等待超時(shí)的記數(shù)變量
private int timeWait = 0;
// .................................................................
// 創(chuàng)建對象池
public void initalPool(PoolParam poolParam, Class clazz) {
this.setPoolParam(poolParam);
this.setClazz(clazz);
stack = new Stack();
stack.clear();
// System.out.println("obj..pool is initial...");
// 生成配置最小對象數(shù),并壓入棧中
try {
for (int i = 0; i < poolParam.getMinObjectCount(); i++) {
// 根據(jù)poolParam初始化對象池
stack.push(clazz.newInstance());
}
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
// 創(chuàng)建單個(gè)對象
private Object createObj(Class clazz) {
Object obj = null;
try {
obj = clazz.newInstance();
// System.out.println("a new one...");
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return obj;
}
// 對象池提供的get方法
public Object getInstance(){
// System.out.println(stack.size());
Object object = null;
if (stack.size() == 0) {
// 如果當(dāng)前棧的長度為0,并且總的對象數(shù)沒有超過定義最大數(shù)
if ((currentNum + poolParam.getMinObjectCount()) < poolParam
.getMaxObjectCount()) {
// 新創(chuàng)建一個(gè)對象
object = this.createObj(clazz);
// 對象數(shù)+1
currentNum++;
} else {
synchronized (this) {
try {
waitme(this);
} catch (Exception e) {
e.printStackTrace();
}
// 獲得通知后檢測棧中是為空,并給出剛剛釋放的資源
if (!stack.empty()) {
object = stack.pop();
}
}
}
} else if (stack.size() > 0) {
object = stack.pop();
// System.out.println(stack.size());
}
return object;
}
// 返回對象的方法
public void returnObj(Object obj) {
if (clazz.isInstance(obj)) {
stack.push(obj);
synchronized (this) {
notify();
}
} else {
System.out.println("this object can not push to stack!");
}
}
// 等待遞歸算法
private void waitme(ObjectPool pool) {
// 等待2s的技術(shù)控制
if (timeWait >= 2000) {
System.out.println("jump up this step..");
timeWait = 0;
return;
} else {
try {
pool.wait(500);
// 等待計(jì)數(shù)累加。。
timeWait +=1000;
System.out.println("waiting time to free obj..");
if (stack.empty()) {
System.out.println("agian....");
waitme(pool);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
管理池類,這個(gè)不是很難,同步了就好
@SuppressWarnings("unchecked")
public class ObjectPoolManage {
private ObjectPoolManage() {
}
private static ObjectPool pool;
// 實(shí)現(xiàn)一個(gè)單例的獲取方法....默認(rèn)
public static synchronized ObjectPool getCacheObject(Class clazz) {
if (null != pool) {
return pool;
} else {
createObjectPool(null, clazz);
return pool;
}
}
// 實(shí)現(xiàn)一個(gè)單例的獲取方法...自定義
public static synchronized ObjectPool getCacheObject(PoolParam p, Class clazz) {
if (null != pool) {
return pool;
} else {
createObjectPool(p, clazz);
return pool;
}
}
private static ObjectPool createObjectPool(PoolParam p, Class clazz) {
pool = new ObjectPool();
if (null == p) {
pool.initalPool(new PoolParam(5,10), clazz);
} else {
pool.initalPool(p, clazz);
}
return pool;
}
private static Class getclazz(){
Class clazz=null;
try {
clazz= Class.forName(ppp.getPropertyByName("objectPath"));
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return clazz;
}
}
相關(guān)問題和實(shí)現(xiàn)
1. 對象池中可以限制對象的個(gè)數(shù),當(dāng)超過限制時(shí),對象池需要返回異常或者空值,以通知客戶。
2. 在多線程環(huán)境中,在checkout和checkin方法需要同步。
3. 定時(shí)清理過期的對象。
- 解析Java編程中設(shè)計(jì)模式的開閉原則的運(yùn)用
- 詳解Java設(shè)計(jì)模式編程中的依賴倒置原則
- 舉例解析Java的設(shè)計(jì)模式編程中里氏替換原則的意義
- 詳解Java設(shè)計(jì)模式編程中的里氏替換原則
- Java結(jié)構(gòu)型設(shè)計(jì)模式中的適配器模式與橋接模式解析
- 講解Java設(shè)計(jì)模式編程中的建造者模式與原型模式
- Java設(shè)計(jì)模式編程中的工廠方法模式和抽象工廠模式
- 淺析Java設(shè)計(jì)模式編程中的單例模式和簡單工廠模式
- Java設(shè)計(jì)模式之裝飾者模式詳解和代碼實(shí)例
- 實(shí)例講解Java設(shè)計(jì)模式編程中的OCP開閉原則
相關(guān)文章
利用JAVA反射,讀取數(shù)據(jù)庫表名,自動生成對應(yīng)實(shí)體類的操作
這篇文章主要介紹了利用JAVA反射,讀取數(shù)據(jù)庫表名,自動生成對應(yīng)實(shí)體類的操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-08-08
SpringBoot項(xiàng)目熱部署的實(shí)現(xiàn)
SpringBoot項(xiàng)目熱部署是一種讓開發(fā)人員在修改代碼后無需重啟應(yīng)用即可看到更改效果的技術(shù),通過使用SpringBoot的DevTools等工具,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-09-09
java HttpServletRequest和HttpServletResponse詳解
這篇文章主要介紹了java HttpServletRequest和HttpServletResponse詳解的相關(guān)資料,需要的朋友可以參考下2016-12-12
java線程中斷?interrupt?和?LockSupport解析
這篇文章主要為大家介紹了java線程中斷?interrupt?和?LockSupport示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02
spring boot org.junit.jupiter.api不存在的解決
這篇文章主要介紹了spring boot org.junit.jupiter.api不存在的解決方案,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09

