在B2B(企業對企業)應用中xml扮演一個重要的角色。在這些應用中采用Simple API for XML (SAX)或者document.nbspObject Model (DOM)解析器來解析xml文件。(這兩個解析器都是java的api,他們可以在下面的附錄中找到)在一個單線程應用中解析是簡單明了的。但是,在多線程的應用中這就是很復雜和具有挑戰性了,比如說做一個應用服務器,因為應用經常會為解析xml創建一個專門的線程,解析的數據用來為許多同時并發運行的線程服務。這篇文章描述了一個在并發應用中的xml的解析實現。
下面的SmartQueue 代碼片斷展示了這種策略的實現。 public synchronized void put(Object data) { // check to see if the length is 2 while (list.size() >= 2) { try { System.out. 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.quot;); }
notifyAll(); return obj; }
xml 解析 這個設計使用SAX API來解析XML文件是有以下原因的: 這個API讀取 XML數據是快速高效的,他不構造任何內部的XML數據描述,相應的,他在碰到XML元素時簡單的把數據傳遞給應用程序。SAX API十分適合生產-消費模式. xml 解析控制器(XMLParserHandler) 的類繼續自SAX,實現回叫(callback )方法從解析器中接收XML數據,當解析控制器類從解析器中接收XML數據時,他把數據put進hashtable里。在每個文檔的結尾,解析控制器把數據put進SmartQueue隊列里。這個控制器將進入一個等待狀態假如SmartQueue隊列里有空間,一旦消費線程從SmartQueue隊列中移去一項,put方法將被調用。在完成整個XML文檔的解析后,解析控制器( XMLParserHandler)通知消費線程停止搜索更多的文檔。
消費線程 消費線程移從SmartQueue隊列中除項目一旦生產線程把項目放入SmartQueue隊列。假如SmartQueue隊列為空,每個消費線程將要進入等待狀態。消費線程會一直運行直到生產線程通知已經達到了文檔元素的結尾而且SmartQueue隊列中再沒有項目了。這里有一個消費線程的例子實現,他保持不斷地從SmartQueue隊列中取數據直到隊列中沒有數據或者達到了文檔元素的末尾。 public void run() { while (!queue.isEmpty() !queue.onEnd()) { Hashtable val = (Hashtable) queue.take();
System.out.println("OBTained by " + this.getName() + " " + val);
例子程序 source.zip文件包括一個TestProdUCerConsumerForXML類可以把xml文件作為一個參數運行。根據下面的說明來運行程序, Unzip the source.zip file. Run the program TestProducerConsumerForXML with order.xml. For example