單線程解析簡單明瞭,但應用伺服器等高併發場景需:專門解析線程生產數據,多工作線程消費處理。傳統DOM佔記憶體大,SAX事件驅動適合流式處理,但需解決生產消費速度失衡問題。
SmartQueue採用固定長度佇列(長度=2),透過wait()/notifyAll()實現背壓控制:
public class SmartQueue {
private final List
public class XMLParserHandler extends DefaultHandler {
private final SmartQueue queue;
private final Map currentData = new HashMap<>();
public XMLParserHandler(SmartQueue queue) { this.queue = queue; }
@Override
public void startElement(String uri, String localName, String qName, Attributes attrs) {
currentData.clear();
for (int i = 0; i < attrs.getLength(); i++) {
currentData.put(attrs.getQName(i), attrs.getValue(i));
}
}
@Override
public void characters(char[] ch, int start, int length) {
String text = new String(ch, start, length).trim();
if (!text.isEmpty()) {
currentData.put("text", text);
}
}
@Override
public void endElement(String uri, String localName, String qName) {
if (!currentData.isEmpty()) {
try {
queue.put(new ParsedElement(qName, new HashMap<>(currentData)));
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
@Override
public void endDocument() {
try {
queue.setEOF();
} catch (Exception e) {
// ignore
}
}
}
public class XMLConsumer implements Runnable {
private final SmartQueue queue;
public XMLConsumer(SmartQueue queue) { this.queue = queue; }
@Override
public void run() {
try {
while (true) {
ParsedElement element = (ParsedElement) queue.take();
if (element == null) break; // EOF
processElement(element); // 業務邏輯處理
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
private void processElement(ParsedElement element) {
// 具體業務處理:資料庫寫入、快取更新、索引建立等
}
}
此模式展現經典生產消費者模式在XML處理中的優雅應用,是高併發系統設計的範本級方案。