【发布时间】:2015-06-13 22:33:00
【问题描述】:
我正在尝试读取具有多个线程的 XML 文档。文件非常大!如果我使用单线程,程序可以工作,但如果我使用工作线程,我会出错。 作为单个线程,加载大约需要 30-40 秒。作为多个线程,大约需要 5 秒。所以优势很明显。但是我就是无法让它工作。 如果有人能对此有所了解,我很想知道。
这是一些代码。不完全是我所拥有的(删除了很多 cmets 和 try-catch 块以及与问题无关的东西)
import org.w3c.dom.*;
import java.net.URL;
private static DocumentBuilder getBuilder() {
try {
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
return dbFactory.newDocumentBuilder();
} catch (ParserConfigurationException ex) {
String err = "error initializing API interface: \n" + ex.getMessage();
System.out.println(err);
JOptionPane.showMessageDialog(null, err, "Loading error", JOptionPane.WARNING_MESSAGE);
System.exit(1);
}
return null;
}
public void loadPage(String page) {
URL url = new URL(page);
Document doc = getBuilder().parse(url.openStream());
Element root = doc.getDocumentElement();
NodeList nodes = root.getChildNodes();
for (int i = 0; i < nodes.getLength(); i++) {
Node n = nodes.item(i);
if (n instanceof Element) {
// move node to new document.
Document doc;
doc = getBuilder().newDocument();
Node nn = doc.adoptNode(n);
doc.appendChild(nn);
Element ele = (Element)nn;
new Parser(ele).start(); // Causes errors...
//new Parser(ele).run(); // Works, but isn't threaded.
NodeList nodes = root.getChildNodes();
i = 0;
}
}
}
public class Parser implements Runnable {
private Element ele;
public Parser(Element e) {
ele = e;
}
public void start() {
new Thread(this).start();
}
@Override
public void run() {
// Parse the document here.
// I get errors here if it's multi-threaded.
}
}
编辑:
错误是损坏的数据。经过进一步测试,我发现问题比我想象的还要严重。上面的函数“loadPage”是从线程调用的。我在发布这个问题时的测试是在只运行一个线程的情况下完成的。但是我发现,如果我在 parrelell 中运行多个页面加载(即使它们是完全不同的页面),即使我每页只使用一个线程,我也会收到错误...
我担心某处使用的静态对象会导致状态损坏并导致我的数据损坏。
损坏数据的一个例子是这样的。
// when reading the XML
// <Date>2015-6-1</Date>
public String getText(Element ele) {
String val = ele.getFirstChild().getNodeValue();
}
// I will get either an empty string or somthing like "13E13" or ".5D4"
通过多个页面加载,我的意思是:
public void loadAll(List<String> pages) {
for(String page : pages) {
new Loader(page).start();
}
}
public class Loader implements Runnable {
private String page;
public Loader(String p) {
page = p;
}
public void start() {
new Thread(this).start();
}
@Override
public void run() {
loadPage(page);
}
}
【问题讨论】:
-
您的错误是什么样的?你能发布一个堆栈跟踪吗?
-
如果您不告诉我们错误是什么,我们将无法帮助您。
-
找到了问题,在我的代码深处,我有一个正在使用的静态 DateFormat 对象。由于错误字符串中报告的值,我认为数据已损坏。
标签: java xml multithreading