典型物件池模型的“物件過早歸還”現象分析 (轉)
常見的池實現方法雖然各不相同,但其卻大同小異,差別主要在於物件池的策略層上。《 Enterprise Design Patterns: Patterns in Java, Volume 3》中給出的物件池模型非常具有代表性。為敘述方便,簡稱為模型1,本文以此模型為物件進行討論。模型1如下圖:
:namespace prefix = o ns = "urn:schemas--com::office" />
圖1 物件池模型1
通常只有當物件可複用時,使用物件池才有意義。圖中Reusable是物件池所管理的可複用物件。應用中的任意(Component)都可以成為Client。圖中,Client透過ReusablePool.acquireReusable從物件池中取出物件,透過ReusablePool.releaseReusable將物件歸還給物件池;每個Reusable物件只能被一個Client 引用。Reusable與Client之間的關係是M:1,這個關係對模型1很重要。因為只有這樣才能保證Client能在任意時刻的 releaseReusable。
從物件池角度來看,Reusable物件Obj要麼在池中,要麼不在。而acquireReusable只能取出池中的物件,所以任意時刻只有一個Client能透過acquireReusable獲得Obj;而在Obj被歸還之前,任何其他Component都無法透過acquireReusable得到Obj。因此只要應用程式總是透過acquireReusable來獲得Reusable物件,就能保證Reusable與Client之間的M:1關係(而且模型1也僅將透過acquireReusable獲取Reusable物件的Component看作Client,當然這只是模型1的主觀意願)。但是由於缺乏機制,應用程式非常輕易的就能繞過acquireReusable而獲得對Obj的引用。例如首先語句ComponentA.obj = Reusable.acquireReusable()取出物件ObjA,並用ComponentA.obj引用ObjA;然後執行賦值操作ComponentB.obj=ComponentA.obj,使ComponentB.obj也引用ObjA。儘管模型1不認為ComponentB是ObjA的Client(因為模型1中ObjA只能有一個Client,此時就是ComponentA),但實際上Reusable與Client之間的M:1關係還是被破壞了。如果ComponentA忽視這個事實,一如既往的呼叫releaseReusable就會引起“物件過早歸還”問題 - 在應用程式的一部分還擁有對Reusable物件的引用時,應用程式的另外一部分將此物件歸還給物件池了。考慮一個具體的例子:
例1:假設在某個應用程式中ComponentA、ComponentB同時執行在兩個不同的執行緒A、B中,下面是此應用程式在操作的干預下的一次執行過程:
l t0時刻,執行緒A執行ComponentA.obj = ReusablePool.acquireReusable(),取出物件ObjA並對它進行初始化;
l t1時刻,執行緒A被中斷,執行緒B被排程,執行緒B執行操作ComponentB.obj=ComponentA.obj;
l t2時刻,執行緒排程發生,執行緒A執行。ComponentA呼叫releaseReusable()歸還ObjA。此時就出現了ComponentB.obj引用了物件池中的物件ObjA的情況,這是很危險的;
l t3時刻,執行緒再次切換,執行緒B執行;
l t4時刻,ComponentB正準備操作ObjA,發生執行緒切換,執行緒A執行。ComponentA再次呼叫acquireReusable(),這次正巧又得到了ObjA,並再次初始化ObjA,設定其狀態;
l t5時刻,執行緒B被排程,ComponentB未意識到ObjA的狀態已經被修改了,繼續操作ObjA。
不難發現,在t5時刻對ComponentB來說ObjA的狀態已經混亂了,可是ComponentB並未意識到這一點,繼續操作ObjA。這樣就出現了“物件過早歸還”問題。“物件過早歸還”問題對應用程式來說可能是災難性的。來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752019/viewspace-958249/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Java 中的物件池實現Java物件
- 物件池簡單實現物件
- 50.C++物件模型的分析(上)(C語言實現物件導向特性)C++物件模型C語言
- Unity實現簡單的物件池Unity物件
- 分析模式:可複用的物件模型模式物件模型
- 基於Apache元件,分析物件池原理Apache元件物件
- Delphi物件模型(Part V) (轉)物件模型
- Delphi物件模型(Part IV) (轉)物件模型
- Delphi物件模型(Part VI) (轉)物件模型
- Delphi物件模型(Part II) (轉)物件模型
- Delphi物件模型(Part III) (轉)物件模型
- C++物件模型:編譯分析C++物件模型編譯
- python 物件池Python物件
- Unity——物件池管理Unity物件
- .NET Core 物件池的使用物件
- jQuery物件和DOM物件之間的轉換實現jQuery物件
- ASP.NET 頁面物件模型 (轉)ASP.NET物件模型
- 歸檔日誌 現象
- 物件池Pools優化物件優化
- netty Recycler物件池Netty物件
- 過早的給方法中 引用物件 設為 null 可被 GC提前回收嗎?物件NullGC
- 物件池技術和通用實現GenericObjectPool物件Object
- 【Privilege】Oracle物件許可權級聯收回現象測試Oracle物件
- C++ 物件模型C++物件模型
- C++物件模型C++物件模型
- 新增模型物件操作模型物件
- c++中的物件模型C++物件模型
- Unity寫個多用物件池Unity物件
- 物件池與享元模式物件模式
- 自定義物件池實踐物件
- 用Java實現一個通用併發物件池Java物件
- iOS 複雜物件的歸檔與反歸檔iOS物件
- [轉] jQuery物件與DOM物件之間的轉換jQuery物件
- Android中的Message類以及Java物件池的實現AndroidJava物件
- jquery物件和DOM物件的互相轉換jQuery物件
- DOM物件與jquery物件的相互轉換物件jQuery
- jQuery物件與Dom物件的相互轉換jQuery物件
- 最近更新過的物件物件