舉例講解Java設(shè)計(jì)模式中的對(duì)象池模式編程
定義
一個(gè)對(duì)象池是一組已經(jīng)初始化過(guò)且可以使用的對(duì)象的集合,池的用戶可以從池子中取得對(duì)象,對(duì)其進(jìn)行操作處理,并在不需要時(shí)歸還給池子而非銷毀它。
若初始化、實(shí)例化的代價(jià)高,且有需求需要經(jīng)常實(shí)例化,但每次實(shí)例化的數(shù)量較少的情況下,使用對(duì)象池可以獲得顯著的效能提升。從池子中取得對(duì)象的時(shí)間是可預(yù)測(cè)的,但新建一個(gè)實(shí)例所需的時(shí)間是不確定。
實(shí)現(xiàn)
1. Reusable - 對(duì)象池中的對(duì)象,通常實(shí)例化代價(jià)比較高。
2. Client - 使用一個(gè)對(duì)象的實(shí)例。
3. ReusablePool - 管理對(duì)象的實(shí)例化,回收和銷毀。
單個(gè)實(shí)例中主要的思想
1.一個(gè)棧,這里用stack
2.初始化方法,容器開(kāi)啟的時(shí)候可以預(yù)先創(chuàng)建池
3.創(chuàng)建實(shí)例的方法
4.提供從池中獲得對(duì)象實(shí)例的方法
5.提供返回的方法,不返回后果很嚴(yán)重
6.控制請(qǐng)求等待時(shí)間的方法,過(guò)了一定的事件還沒(méi)獲得對(duì)象實(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)前總對(duì)象個(gè)數(shù) private int currentNum = 0; private Class clazz; public void setClazz(Class clazz) { this.clazz = clazz; } // 棧,用來(lái)存放對(duì)象,模擬一個(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)建對(duì)象池 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..."); // 生成配置最小對(duì)象數(shù),并壓入棧中 try { for (int i = 0; i < poolParam.getMinObjectCount(); i++) { // 根據(jù)poolParam初始化對(duì)象池 stack.push(clazz.newInstance()); } } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } // 創(chuàng)建單個(gè)對(duì)象 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; } // 對(duì)象池提供的get方法 public Object getInstance(){ // System.out.println(stack.size()); Object object = null; if (stack.size() == 0) { // 如果當(dāng)前棧的長(zhǎng)度為0,并且總的對(duì)象數(shù)沒(méi)有超過(guò)定義最大數(shù) if ((currentNum + poolParam.getMinObjectCount()) < poolParam .getMaxObjectCount()) { // 新創(chuàng)建一個(gè)對(duì)象 object = this.createObj(clazz); // 對(duì)象數(shù)+1 currentNum++; } else { synchronized (this) { try { waitme(this); } catch (Exception e) { e.printStackTrace(); } // 獲得通知后檢測(cè)棧中是為空,并給出剛剛釋放的資源 if (!stack.empty()) { object = stack.pop(); } } } } else if (stack.size() > 0) { object = stack.pop(); // System.out.println(stack.size()); } return object; } // 返回對(duì)象的方法 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)問(wèn)題和實(shí)現(xiàn)
1. 對(duì)象池中可以限制對(duì)象的個(gè)數(shù),當(dāng)超過(guò)限制時(shí),對(duì)象池需要返回異常或者空值,以通知客戶。
2. 在多線程環(huán)境中,在checkout和checkin方法需要同步。
3. 定時(shí)清理過(guò)期的對(duì)象。
- 解析Java編程中設(shè)計(jì)模式的開(kāi)閉原則的運(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ì)模式編程中的單例模式和簡(jiǎn)單工廠模式
- Java設(shè)計(jì)模式之裝飾者模式詳解和代碼實(shí)例
- 實(shí)例講解Java設(shè)計(jì)模式編程中的OCP開(kāi)閉原則
相關(guān)文章
Java String轉(zhuǎn)換時(shí)為null的解決方法
這篇文章主要介紹了Java String轉(zhuǎn)換時(shí)為null的解決方法,需要的朋友可以參考下2017-07-07SpringBoot項(xiàng)目打成War布署在Tomcat的詳細(xì)步驟
這篇文章主要介紹了SpringBoot項(xiàng)目打成War布署在Tomcat,本文分步驟結(jié)合圖文實(shí)例給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-03-03idea全局設(shè)置Maven配置的實(shí)現(xiàn)步驟
本文主要介紹了idea全局設(shè)置Maven配置,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07maven項(xiàng)目打包上傳到私有倉(cāng)庫(kù)
在項(xiàng)目開(kāi)發(fā)中通常會(huì)引用其他的jar,怎樣把自己的項(xiàng)目做為一個(gè)jar包的形式發(fā)布到私服倉(cāng)庫(kù)中,本文就詳細(xì)的介紹一下,感興趣的可以了解一下2021-06-06SpringBoot加密配置文件的SQL賬號(hào)密碼方式
這篇文章主要介紹了SpringBoot加密配置文件的SQL賬號(hào)密碼方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-06-06