在B2B(企業對企業)應用中XML扮演一個重要的角色。在這些應用中采用Simple API for XML (SAX)或者document.nbspObject Model (DOM)解析器來解析xml文件。(這兩個解析器都是Java的api,他們可以在下面的附錄中找到)在一個單線程應用中解析是簡單明了的。
<!-- frame contents -->
<!-- /frame contents -->
但是,在多線程的應用中這就是很復雜和具有挑戰性了,比如說做一個應用服務器,因為應用經常會為解析xml創建一個專門的線程,解析的數據用來為許多同時並發運行的線程服務。這篇文章描述了一個在並發應用中的xml的解析實現。
設計方法 基於並發的生產和消費設計概念,一個專門的線程作為一個生產者去解析xml。一組線程作為消費者,作為解析xml數據的生產線程,他把數據存儲在一個共享的數據結構中以供消費線程在將來進行處理時取得,為了最大化產生數據的能力同時最小化內存的使用,這個設計使用了一個非凡的隊列來分別為生產者、消費者存儲和找到解析的數據.
巧妙的隊列(Smart Queuing) SmartQueue 隊列類提供給生產消費線程們隊列的功能,他主要的責任是維護隊列防止(線程)超載和斷流。換句話說,SmartQueue采用維護一個固定長度的隊列的方法去保持資源的應用效率。他掛起和喚醒適當的線程在適當的時候,打個比方,假如沒有填充數據的空間,隊列將掛起生產線程直到一個消費線程從隊列裡移去一項。
下面的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.quot;);
}
notifyAll();
return obj;
}
xml 解析 這個設計使用SAX API來解析XML文件是有以下原因的:
這個API讀取 XML數據是快速高效的,他不構造任何內部的XML數據描述,相應的,他在碰到XML元素時簡單的把數據傳遞給應用程序。SAX API十分適合生產-消費模式。
<!-- frame contents -->
<!-- /frame contents -->
xml 解析控制器(XMLParserHandler) 的類繼續自SAX,實現回叫(callback )方法從解析器中接收XML數據,當解析控制器類從解析器中接收XML數據時,他把數據put進hashtable裡。在每個文檔的結尾,解析控制器把數據put進SmartQueue隊列裡。這個控制器將進入一個等待狀態假如SmartQueue隊列裡有空間,一旦消費線程從SmartQueue隊列中移去一項,put方法將被調用。在完成整個XML文檔的解析後,解析控制器(