首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 程式設計入門

XML生產消費者模式:多線程環境下SAX解析的高併發架構設計

     編輯:Java 程式設計入門

多線程XML解析挑戰

單線程解析簡單明瞭,但應用伺服器等高併發場景需:專門解析線程生產數據,多工作線程消費處理。傳統DOM佔記憶體大,SAX事件驅動適合流式處理,但需解決生產消費速度失衡問題。

智慧佇列核心設計

SmartQueue採用固定長度佇列(長度=2),透過wait()/notifyAll()實現背壓控制:

public class SmartQueue {
    private final List list = new ArrayList<>();
    private volatile boolean eof = false;
    private static final int CAPACITY = 2;
    
    public synchronized void put(Object data) throws InterruptedException {
        while (list.size() >= CAPACITY) {
            wait();  // 佇列滿,掛起生產者
        }
        list.add(data);
        notifyAll(); // 喚醒消費者
    }
    
    public synchronized Object take() throws InterruptedException {
        while (list.isEmpty() && !eof) {
            wait();  // 佇列空且未結束,掛起消費者
        }
        if (list.isEmpty()) return null; // EOF信號
        Object obj = list.remove(0);
        notifyAll(); // 喚醒生產者
        return obj;
    }
    
    public synchronized void setEOF() {
        eof = true;
        notifyAll();
    }
}

SAX解析生產者實現

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文檔OOM
  • 背壓自然形成:消費慢→佇列滿→生產阻塞,無需額外協調
  • 解耦合清晰:解析邏輯與業務邏輯完全分離,可獨立擴展
  • 多消費者支援:啟動多個Consumer線程並行處理,提升吞吐

適用場景

  • 大型XML報文處理(金融匯款、電信話單、物流軌跡)
  • 異步數據管線:Kafka/HTTP → XML解析 → 業務處理
  • ETL數據抽取轉換載入流程

此模式展現經典生產消費者模式在XML處理中的優雅應用,是高併發系統設計的範本級方案。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved