Dan*_*Dan 3 java xml concurrency xpath dom4j
我计划在多个线程可以查询文档的应用程序中使用dom4j DOM Document作为静态缓存.考虑到文档本身永远不会改变的帐户,从多个线程查询它是否安全?
我写了下面的代码来测试它,但我不确定它确实证明操作是安全的吗?
package test.concurrent_dom;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Node;
/**
* Hello world!
*
*/
public class App extends Thread
{
private static final String xml =
"<Session>"
+ "<child1 attribute1=\"attribute1value\" attribute2=\"attribute2value\">"
+ "ChildText1</child1>"
+ "<child2 attribute1=\"attribute1value\" attribute2=\"attribute2value\">"
+ "ChildText2</child2>"
+ "<child3 attribute1=\"attribute1value\" attribute2=\"attribute2value\">"
+ "ChildText3</child3>"
+ "</Session>";
private static Document document;
private static Element root;
public static void main( String[] args ) throws DocumentException
{
document = DocumentHelper.parseText(xml);
root = document.getRootElement();
Thread t1 = new Thread(){
public void run(){
while(true){
try {
sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
Node n1 = root.selectSingleNode("/Session/child1");
if(!n1.getText().equals("ChildText1")){
System.out.println("WRONG!");
}
}
}
};
Thread t2 = new Thread(){
public void run(){
while(true){
try {
sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
Node n1 = root.selectSingleNode("/Session/child2");
if(!n1.getText().equals("ChildText2")){
System.out.println("WRONG!");
}
}
}
};
Thread t3 = new Thread(){
public void run(){
while(true){
try {
sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
Node n1 = root.selectSingleNode("/Session/child3");
if(!n1.getText().equals("ChildText3")){
System.out.println("WRONG!");
}
}
}
};
t1.start();
t2.start();
t3.start();
System.out.println( "Hello World!" );
}
}
Run Code Online (Sandbox Code Playgroud)
http://xerces.apache.org/xerces2-j/faq-dom.html说
不.DOM不要求实现是线程安全的.如果需要从多个线程访问DOM,则需要向应用程序代码添加适当的锁.
在没有看到实现的情况下,不可能知道是否selectSingleNode
使用任何共享状态来读取DOM.我认为最安全的做法是假设它不是线程安全的.
另一种方法是使用自己的XPath处理器,例如Jaxen,它是线程安全的.
XPath对象是完全可重入且线程安全的.它们不包含用于评估的内部状态,因此可以在应用程序中轻松缓存和共享.一旦有了XPath对象,就可以将它应用于各种初始上下文,并以几种不同的方式检索结果:--- SAX路径和Jaxen简介
JAXEN Jira针对线程安全问题提供了各种修复,提供了Jaxen设计为线程安全的证据.这是一个我偶然碰到.并确认 Jaxen是其中一位作者的线程安全.
除了线程安全之外,Jaxen与模型无关 - 它适用于许多模型(W3C DOM,XOM,Dom4J,JDOM),并且可以通过实现几个接口来插入自定义模型.
我认为W3C DOM上的简单访问器和迭代器是线程安全的.但这只是一种预感,而不是一个具体的事实.如果你想100%确定,那么使用专为thread-saftey设计的DOM,例如dom4j.
一些入门资源: - 使用Jaxen的一个例子.- Jaxen常见问题和主页
归档时间: |
|
查看次数: |
3028 次 |
最近记录: |