在B2B(企業(yè)對企業(yè))應(yīng)用中xml扮演一個重要的角色。在這些應(yīng)用中采用Simple API for XML (SAX)或者document.nbspObject Model (DOM)解析器來解析xml文件。(這兩個解析器都是java的api,他們可以在下面的附錄中找到)在一個單線程應(yīng)用中解析是簡單明了的。但是,在多線程的應(yīng)用中這就是很復(fù)雜和具有挑戰(zhàn)性了,比如說做一個應(yīng)用服務(wù)器,因為應(yīng)用經(jīng)常會為解析xml創(chuàng)建一個專門的線程,解析的數(shù)據(jù)用來為許多同時并發(fā)運(yùn)行的線程服務(wù)。這篇文章描述了一個在并發(fā)應(yīng)用中的xml的解析實現(xiàn)。
下面的SmartQueue 代碼片斷展示了這種策略的實現(xiàn)。 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 解析 這個設(shè)計使用SAX API來解析XML文件是有以下原因的: 這個API讀取 XML數(shù)據(jù)是快速高效的,他不構(gòu)造任何內(nèi)部的XML數(shù)據(jù)描述,相應(yīng)的,他在碰到XML元素時簡單的把數(shù)據(jù)傳遞給應(yīng)用程序。SAX API十分適合生產(chǎn)-消費(fèi)模式. xml 解析控制器(XMLParserHandler) 的類繼續(xù)自SAX,實現(xiàn)回叫(callback )方法從解析器中接收XML數(shù)據(jù),當(dāng)解析控制器類從解析器中接收XML數(shù)據(jù)時,他把數(shù)據(jù)put進(jìn)hashtable里。在每個文檔的結(jié)尾,解析控制器把數(shù)據(jù)put進(jìn)SmartQueue隊列里。這個控制器將進(jìn)入一個等待狀態(tài)假如SmartQueue隊列里有空間,一旦消費(fèi)線程從SmartQueue隊列中移去一項,put方法將被調(diào)用。在完成整個XML文檔的解析后,解析控制器( XMLParserHandler)通知消費(fèi)線程停止搜索更多的文檔。
消費(fèi)線程 消費(fèi)線程移從SmartQueue隊列中除項目一旦生產(chǎn)線程把項目放入SmartQueue隊列。假如SmartQueue隊列為空,每個消費(fèi)線程將要進(jìn)入等待狀態(tài)。消費(fèi)線程會一直運(yùn)行直到生產(chǎn)線程通知已經(jīng)達(dá)到了文檔元素的結(jié)尾而且SmartQueue隊列中再沒有項目了。這里有一個消費(fèi)線程的例子實現(xiàn),他保持不斷地從SmartQueue隊列中取數(shù)據(jù)直到隊列中沒有數(shù)據(jù)或者達(dá)到了文檔元素的末尾。 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文件作為一個參數(shù)運(yùn)行。根據(jù)下面的說明來運(yùn)行程序, Unzip the source.zip file. Run the program TestProducerConsumerForXML with order.xml. For example