用java并行构造XML元素

用java并行构造XML元素,java,xml,multithreading,java-8,Java,Xml,Multithreading,Java 8,我有一个对象数组,我正从中使用java构建一个xml文档,如下所示- Object[] arr = fetchData(); Document newDoc =DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); Element rootElement = newDoc.createElement("company"); for(int i=0;i<arr.length();i++) { E

我有一个对象数组,我正从中使用java构建一个xml文档,如下所示-

Object[] arr = fetchData();
Document newDoc =DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
Element rootElement = newDoc.createElement("company");
for(int i=0;i<arr.length();i++)
{
    Element staff = new Element("staff");
    staff.setAttribute(new Attribute("id", i));
    staff.addContent(new Element("firstname").setText(arr[i].getFirstName()));
    staff.addContent(new Element("lastname").setText(arr[i].getLastName()));
    staff.addContent(new Element("nickname").setText(arr[i].getNickName()));
    staff.addContent(new Element("salary").setText(arr[i].getSalary()));
    ............
    ............
    ............
    ............
    ............
    rootElement.appendChild(staff);
}
newDoc.appendChild(rootElement);
Object[]arr=fetchData();
Document newDoc=DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
Element rootElement=newDoc.createElement(“公司”);
对于(int i=0;i getElement(newDoc,e));
添加(f);
}
用于(可完成的未来e:未来元素)
appendChild(e.get());
newDoc.appendChild(根元素);
您可以使用的是s

通过这种方式,您可以在一个新线程中生成所有“staff”元素,然后等待它们全部完成并添加它们

List<CompletableFuture<Element>> futureElements = new ArrayList<>()
for(int x = 0; x < arr.length; x++){
     //getElement(arr[x]) is the get staff element logic
     CompletableFuture<Element> f = CompletableFuture.supplyAsync(() -> getElement(arr[x]))
     futureElements.add(f);
}

CompletableFuture<Void> allOf = CompletableFuture.allOf(futureElements.toArray(new CompletableFuture[0]))

如果通过
新元素
创建元素,则不使用标准DOM API。我们无法猜测未指定的非标准库的线程安全性。感谢您的快速响应,我已经更新了代码。使用线程最简单的方法是使用一个对象封装名称、昵称、薪水(等等),将这些元素中的每一个放在一个并发集合中,并让多个线程轮询并发集合,直到其为空,创建必要的元素,然后应用所有这些来创建树(如果元素应按id排序,则可能需要添加同步或后期处理)。现在,如果您展示用于创建XML树的库,它可能有助于提供一个具体的实现,因为
DocumentBuilderFactory.newInstance()
可能返回任意的
DocumentBuilder
实现,因此无法保证它是线程安全的,更糟糕的是,节点是通过
文档
接口创建的,并且始终与文档关联,这就要求实现者维护结合这些工件的隐藏数据结构,这些工件不太可能是线程安全的。如果性能是一个问题,那么您应该问问自己是否真的需要一个
DocumentBuilder
,或者组装XML
字符串的轻量级代码是否也可以。后者可以是并行的…感谢您提供了上述解决方案,我修改了我的代码以使用上述逻辑,但我没有看到任何性能改进,而是因为它会降低大型数据集的性能,用我的解决方案更新了问题。
Object[] arr = fetchData();
Document newDoc =DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
Element rootElement = newDoc.createElement("company");
List<CompletableFuture<Element>> futureElements = new ArrayList<>();
for (int x = 0; x < arr.length(); x++) {
    Object e = arr[x];
    CompletableFuture<Element> f = CompletableFuture.supplyAsync(() -> getElement(newDoc, e));
    futureElements.add(f);
}

for (CompletableFuture<Element> e : futureElements)
        rootElement.appendChild(e.get());

newDoc.appendChild(rootElement); 
List<CompletableFuture<Element>> futureElements = new ArrayList<>()
for(int x = 0; x < arr.length; x++){
     //getElement(arr[x]) is the get staff element logic
     CompletableFuture<Element> f = CompletableFuture.supplyAsync(() -> getElement(arr[x]))
     futureElements.add(f);
}

CompletableFuture<Void> allOf = CompletableFuture.allOf(futureElements.toArray(new CompletableFuture[0]))
futureElements.forEach(f -> rootElement.append(f.get()));