在 B2B 企業級應用中,XML 扮演關鍵資料交換格式。傳統單執行緒解析雖簡單,但在多執行緒應用伺服器環境下,需為並發請求建立專屬解析執行緒,並將解析資料高效分發給多個工作執行緒。本文提出基於生產者-消費者模式的並發 XML 解析架構。
核心思想:單一生產者執行緒負責解析 XML,多個消費者執行緒處理解析後的資料。為平衡生產與消費速度、避免記憶體溢位,引入固定長度的 SmartQueue:
public synchronized void put(Object data) {
while (list.size() >= 2) { // 固定長度 2
try { wait(); } catch (Exception ex) {}
}
list.add(data);
notifyAll();
}
public synchronized Object take() {
while (list.size() <= 0 && !eof) {
try { wait(); } catch (Exception ex) {}
}
Object obj = null;
if (list.size() > 0) {
obj = list.remove(0);
}
notifyAll();
return obj;
}
選用 SAX API 因其流式讀取、低記憶體佔用、適合生產-消費模式。XMLParserHandler 繼承 DefaultHandler,實現回呼方法:
startElement:遇到目標元素(如 elemmark)建立新 Hashtable 承載單筆記錄characters:累積元素文字內容endElement:元素結束時將資料放入 SmartQueue,隊列滿則阻塞endDocument:設定 EOF 標記,喚醒所有消費者public void startElement(String namespaceURI, String localName, String qName, Attributes atts) {
if (qName.equalsIgnoreCase(elemmark)) {
doc = new Hashtable();
}
elem = qName;
}
public void endElement(String namespaceURI, String localName, String qName) {
String s = sbData.toString();
if (qName.equalsIgnoreCase(elemmark)) {
smartQueue.put(doc); // 阻塞直到有空位
doc = null;
}
}
public void endDocument() {
smartQueue.end(); // 標記結束,喚醒消費者
}
消費者持續從隊列取出 Hashtable 處理,直到隊列為空且 EOF 為真:
public void run() {
while (!queue.isEmpty() || !queue.onEnd()) {
Hashtable val = (Hashtable) queue.take();
// 處理業務邏輯...
}
}
SmartQueue 的 put/take 邏輯可實現不同緩衝策略XMLParserHandler 可擴充產生應用專屬物件,而非通用 Hashtablejava -classpath . prodcons.TestProducerConsumerForXML order.xml
原始碼包含完整示範,展示執行緒協作與資料流向。