在B2B(企业对企业)应用中xml扮演一个重要的角色。在这些应用中采用Simple API for XML (SAX)或者document.nbspObject Model (DOM)解析器来解析xml文件。(这两个解析器都是java的api,他们可以在下面的附录中找到)在一个单线程应用中解析是简单明了的。但是,在多线程的应用中这就是很复杂和具有挑战性了,比如说做一个应用服务器,因为应用经常会为解析xml创建一个专门的线程,解析的数据用来为许多同时并发运行的线程服务。这篇文章描述了一个在并发应用中的xml的解析实现。
下面的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十分适合生产-消费模式. xml 解析控制器(XMLParserHandler) 的类继续自SAX,实现回叫(callback )方法从解析器中接收XML数据,当解析控制器类从解析器中接收XML数据时,他把数据put进hashtable里。在每个文档的结尾,解析控制器把数据put进SmartQueue队列里。这个控制器将进入一个等待状态假如SmartQueue队列里有空间,一旦消费线程从SmartQueue队列中移去一项,put方法将被调用。在完成整个XML文档的解析后,解析控制器( XMLParserHandler)通知消费线程停止搜索更多的文档。
消费线程 消费线程移从SmartQueue队列中除项目一旦生产线程把项目放入SmartQueue队列。假如SmartQueue队列为空,每个消费线程将要进入等待状态。消费线程会一直运行直到生产线程通知已经达到了文档元素的结尾而且SmartQueue队列中再没有项目了。这里有一个消费线程的例子实现,他保持不断地从SmartQueue队列中取数据直到队列中没有数据或者达到了文档元素的末尾。 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文件作为一个参数运行。根据下面的说明来运行程序, Unzip the source.zip file. Run the program TestProducerConsumerForXML with order.xml. For example