| XML?Parsing?in?a?Producer-Consumer?Model | | mem_fox 翻譯? (參與分:425,專家分:410)?? 發表:2003-11-10 下午11:16 ??版本:1.0 ??閱讀:1520次 |
|
??顯示XML數據是集成B2B應用程序的重要角色。一般應用程序可以實用SAX或者DOM的方式解析XML文件。在單線程的環境下解析XML的程序是非常簡單的,但在多線程的模式下,這項工作就會變得相當的復雜。比如在應用服務器一般會創建一個專用的線程去解析XML數據,并將解析數據提供給一個或多個其他線程使用。現在我們開始實現這樣的XML解析程序.
Design?Approach(設計實現) ??按照producer-consumer的程序設計思想,需要一個專門的線程來扮演生成者去解析XML數據,而另外的一個線程組則充當消費者的角色。生成者在解析XML數據的同時保存結果一個共享的數據結構中,以供消費者來獲取當前的處理結果。這個設計使用一個特殊的隊列讓生成者和消費者可以分別保持和獲取解析的結果,以達到最大的吞吐量和最小的內存消耗。
Smart?Queuing ??SmartQueue類為producer-consumer線程組提供隊列服務。SmartQueue類的主要功能就是管理隊列的長度。換句話說,就是使用固定長度隊列策略有效的維護資源。通過掛起和喚醒適當的線程以保證隊列的長度。比如當需要添加數據是,發現已經沒有位置,則掛起生產者線程,直到有消費者線程移除一些數據。 下面的代碼片段為策略的實現:
public?synchronized?void?put(Object?data)?{ ????//?check?to?see?if?the?length?is?2 ????while?(list.size()?>=?2)?{ ????????try?{ ????????????System.out.println("Waiting?to?put?data"); ????????????wait(); ????????} ????????catch?(Exception?ex)?{ ????????} ????}
????list.add(data); ????notifyAll(); }
public?synchronized?Object?take()?{ ????//?wait?until?there?is?data?to?get ????//?come?out?if?the?end?of?file?signaled ????while?(list.size()?<=?0?&&?(eof?!=?true))?{ ????????try?{? ????????????System.out.println("Waiting?to?consume?data"); ????????????wait(); ????????}?catch?(Exception?ex)?{ ????????} ????}
????Object?obj?=?null;
????if?(list.size()?>?0)?{ ????????obj?=?list.remove(0); ????}?else?{ ????????System.out.println("Woke?up?because?end?of?document"); ????}
????notifyAll(); ????return?obj; }
XML?Parsing 為什么使用SAX的方式來解析XML數據 ??????不創建任何的內部XML數據描述,而只是在遇見元素是簡單的將數據發送到應用程序 ????隨最快和最高效的讀取XML數據的方法 ????API很時候producerconsumer模型 ??XMLParserHandler類繼承SAX,實現了通過方法回調的方式獲取解析的XML數據。當XMLParserHandler將從Parser中獲取的數據保存到Hahstablezhong。當到Element的結尾處時,則將Hashtable對象put進SmartQueue隊列。當SmartQueue沒有空閑位置時,Handler則進入等待狀態直到消費線程移除數據后,put方法才可以完成。當XML文檔完全解析后,XMLParseHandler會通知消費線程停止尋找更多的數據。 ?讓我們著眼于如何用回調的方法向SmartQueue中保存數據并喚醒等待的消費者線程。StartElemetn方法為每個Elemetn實例化一個新的Hashtable.? public?void?startElement(?String?namespaceURI,?String?localName, ????String?qName,?Attributes?atts?) ????throws?SAXException?{ ????System.out.println( ????????"?startElement?local?names............."?+ ????????localName?+?"?"?+?qName); ????????if?(qName.equalsIgnoreCase(elemmark))?{ ????????????doc?=?new?Hashtable(); ????????} ????elem?=?qName; }
在endElement方法中則負責將解析的XML數據添到SmartQueue隊列中。就象上面提到的,SmartQueue隊列hold當前的線程到有空閑空間存儲數據。 public?void?endElement(?String?namespaceURI,?String?localName, ????String?qName?) ????throws?SAXException?{ ????String?s?=?sbData.toString();
????System.out.println("element?"?+?elem?+?"?character?"?+?s);
????if?((doc?!=?null)?&?(s?!=?null)?&?!(s.trim().equals(""))) ????????doc.put(elem,?s);
????sbData?=?new?StringBuffer(); ????System.out.println("?endElement?ending?element............."?+?qName);
????if?(qName.equalsIgnoreCase(elemmark))?{ ????????System.out.println( ????????????"?endElement?ending?element............."?+?localName);
????????smartQueue.put(doc); ????????doc?=?null; ????} }
?最后在endDocument的回調方法中通知所有的消費者線程文檔解析結束。這意味這所有的消費者線程在其結束自己工作之前,不再需要等待更多的數據 public?void?endDocument()?throws?SAXException?{ ????smartQueue.end(); ????System.out.println("End?Document............."); }
Consumer?Threads 消費者線程從SmartQueue隊列中讀取生產者線程存儲的數據。當SmartQueu隊列中沒有數據是,所有的消費者線程都進入等待狀態。當生產者線程發出文檔解析結束的信號和SmartQueue隊列中的數據為空時,消費線程結束。下面的代碼就實現的如何讓消費線程在沒有數據的時候等待,而在文件解析結束和SmartQueue中不在有任何數據的時候結束線程運行。 public?void?run()?{ ????while?(!queue.isEmpty()?||?!queue.onEnd())?{ ????????Hashtable?val?=?(Hashtable)?queue.take();
????????System.out.println("Obtained?by?"?+?this.getName()?+?"?"?+?val);
????????//?try?{ ????????//?????System.out.println("Simulate?lengthy?processing..........."); ????????//?????Thread.sleep(2000); ????????//?} ????????//?catch(Exception?ex){} ????} }
Benefits 這個設計有以下的優點 ??解析數據和使用數據可以并行處理 ??可以用較小的內存使用量,解析大的XML文件
Extending?the?Design ?現在的SmartQueue是在定長的策略下有效的管理內存數據,我們可以定義不同的策略實現Take和Put方法。就象上面提到的,可以建立專用的對象來代替Hashtable來保存XMLParserHandler解析的XML元素和值。
PS?我知道我翻譯的水平很爛,希望大家可以指正。只是感覺這篇文章和設計模式結合的很好介紹給大家,如果有任何評論歡迎到?用代碼說話,那個是我的新blog
|
|
轉載于:https://www.cnblogs.com/sunsonbaby/archive/2004/09/10/41947.html
總結
以上是生活随笔為你收集整理的XML Parsing in a Producer-Consumer Model的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。