我们从xml文件创建Document对象如下。
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setValidating(true);
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse("D:/ABC.xml");
document.normalize();
从创建的文档逻辑中获取子节点如下所示。
public void getDataFromXML()
{
Node rootElement = document.getDocumentElement();
int childsCount = rootElement.getChildNodes().getLength();
for(index = 0; index < childsCount; index ++ )
{
Node item = rootElement.getChildNodes().item(index);
printXMLNode(item);
}
}
public synchronized void printXMLNode(Node xmlNode)
{
int nodesLength = xmlNode.getChildNodes().getLength();
System.out.println("XML-DEBUG : "+xmlNode);
for(int attribCount = 0; attribCount < nodesLength; ++ attribCount)
{
Node attribute = xmlNode.getChildNodes().item(attribCount);
System.out.println("\t\t "+attribCount+" "+attribute);
}
}
两个线程试图从不同的地方调用相同的方法: 一个线程调用的Ex在下面:
Thread test = new Thread(){
public void run()
{
while(true)
{
getDataFromXML();
}
}
};
test.start();
输入XML是:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE Script SYSTEM "Script.dtd">
<Script>
<setValue>
<Label>User Name</Label>
<Value>sysadmin</Value>
</setValue>
<setValue>
<Label>Password</Label>
<Value>XXX</Value>
</setValue>
<click>
<Label>Login</Label>
</click>
<click>
<Label>Purchasing Super User</Label>
</click>
<click>
<Label>Requisitions[1]</Label>
</click>
<click>
<Label>Requisitions[2]</Label>
</click>
<SetText>
<Value>Vision Operations</Value>
</SetText>
<KeyPress>
<Label>Operating Unit0</Label>
</KeyPress>
<SetText>
<Value>Purchase Requisition</Value>
</SetText>
<KeyPress>
<Label>Type0</Label>
</KeyPress>
<SetText>
<Label>Description</Label>
<Value/>
<Disable>True</Disable>
<Comment/>
</SetText>
<KeyPress>
<Label>Description0</Label>
</KeyPress>
</Script>
方法(printXMLNode)的输出在某些节点的不同时间会有所不同(每次都不适用于同一节点)。 有时候,预期的结果会出现,但有时却没有。
例如,对于SetText节点,预期输出为:
XML-DEBUG : [SetText: null]
0 [#text:
1 [Value: null]
2 [#text:
Strage输出是:
XML-DEBUG : [SetText: null]
0 [setValue: null]
1 [setValue: null]
2 [click: null]
3 [click: null]
4 [click: null]
5 [click: null]
6 [SetText: null]
7 [KeyPress: null]
8 [SetText: null]
9 [KeyPress: null]
10 [SetText: null]
11 [KeyPress: null]
无法理解为什么结果会发生变化。很少有线程尝试从此方法获取数据,这就是为什么我们将此方法保持为同步,即使问题仍然存在。 有人可以帮帮忙吗?
答案 0 :(得分:0)
正如您似乎意识到的那样,DOM不是线程安全的。您已经同步了一个访问DOM的方法,但是您的方法getDataFromXML也使用DOM方法并且未同步。
如果您需要多线程,则有比DOM更好的API。如果所有线程都只是读取,JDOM2和XOM都是线程安全的(我相信)。
更好的是,在XQuery或XSLT中完成所有工作。