出产-消费模式的XML理会
当前位置:以往代写 > JAVA 教程 >出产-消费模式的XML理会
2019-06-14

出产-消费模式的XML理会

出产-消费模式的XML理会

副标题#e#

在B2B(企业对企业)应用中XML饰演一个重要的脚色。在这些应用中回收Simple API for XML (SAX)可能document.nbspObject Model (DOM)理会器来理会xml文件。(这两个理会器都是java的api,他们可以在下面的附录中找到)在一个单线程应用中理会是简朴明白的。可是,在多线程的应用中这就是很巨大和具有挑战性了,好比说做一个应用处事器,因为应用常常会为理会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;
}


#p#副标题#e#

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)通知消费线程遏制搜索更多的文档。

让我们看看回叫(callback )要领,他把数据存储入SmartQueue行列然后通知期待的消费线程。起始元素(startElement)要领为每个XML文件中的每个文挡元素示例一个新的Hashtable。

public void startElement( String namespaceURI, String localName,
String qName, Attributes atts )
throws SAXException {
System.out.println(
" startElement local names............." +
localName + " " + qName);
if (qName.equalsIgnoreCase(elemmark)) {
doc = new Hashtable();
}
elem = qName;
}

末了元素(endElement)要领认真把理会的数据加到SmartQueue行列中。就象前面提起的,SmartQueue行列挂起这个线程直到没有空间来存储数据。

public void endElement( String namespaceURI, String localName,String qName )
throws SAXException {
String s = sbData.toString();
if (qName.equalsIgnoreCase(elemmark)) {
System.out.println(
" endElement ending element............." + localName);
smartQueue.put(doc);
doc = null;
}
}

最终,末了文档元素(enddocument.nbsp)回叫要领通知消费线程达到了xml文档的末了。这意味着消费线程不消去期待其他数据完成他们的事情。

public void enddocument.) throws SAXException {
smartQueue.end();
System.out.println("End document.............");
}

#p#副标题#e#

消费线程

消费线程移从SmartQueue行列中除项目一旦出产线程把项目放入SmartQueue行列。假如SmartQueue行列为空,每个消费线程将要进入期待状态。消费线程会一直运行直到出产线程通知已经到达了文档元素的末了并且SmartQueue行列中再没有项目了。这里有一个消费线程的例子实现,他保持不绝地从SmartQueue行列中取数据直到行列中没有数据可能到达了文档元素的末端。

#p#分页标题#e#

public void run() {
while (!queue.isEmpty() || !queue.onEnd()) {
Hashtable val = (Hashtable) queue.take();
System.out.println("Obtained by " + this.getName() + " " + val);
// try {
// System.out.println("Simulate lengthy
processing...........");
// Thread.sleep(2000);
// }
// catch(Exception ex){}
}
}

利益

这个设计有以下利益:

理会和数据消费可以并发的举办。大的xml文件只用很少的内存就能被理会

设计的扩展

SmartQueue行列执行牢靠长度行列的计策来维护内存的效率。改变它的T取(take)和存(put)要领,你能执行一个差异的计策。在前面提到的,xml理会节制器(XMLParserHandler)发生一个xml元素和值的hashtable。然而,这个类可以被定制去成立应用指定的工具。

例子措施

source.zip文件包罗一个TestProducerConsumerForXML类可以把xml文件作为一个参数运行。按照下面的说明来运行措施:

Unzip the source.zip file.
Run the program TestProducerConsumerForXML with order.xml.
For example

c:\testarea>java -classpath \
c:\testarea prodcons.TestProducerConsumerForXML \
c:\testarea\prodcons\order.xml

这篇文章用一些措施描写了理会xml文档元素的要领,也表明白一些关于出产和消费模式的观念,尚有和线程的应用。

    关键字:

在线提交作业