Java在线程中解析和更新xml值
我写了一个多线程程序,每个线程需要解析一个xml文件并更新新值。问题:假设我有一个ABC的xml内容,现在线程a解析xml并将其更新为ABCA,同时线程B也解析xml(内容是ABC)并将其更新为ABCB。线程B在线程A更新后更新xml,因此xml的结果是ABCB,我想要的是xml结果应该是ABCAB。有没有办法控制线程中解析和更新的方式? 这是我的密码: WSthread.javaJava在线程中解析和更新xml值,java,xml,Java,Xml,我写了一个多线程程序,每个线程需要解析一个xml文件并更新新值。问题:假设我有一个ABC的xml内容,现在线程a解析xml并将其更新为ABCA,同时线程B也解析xml(内容是ABC)并将其更新为ABCB。线程B在线程A更新后更新xml,因此xml的结果是ABCB,我想要的是xml结果应该是ABCAB。有没有办法控制线程中解析和更新的方式? 这是我的密码: WSthread.java public class WSthread extends Thread { public String
public class WSthread extends Thread {
public String WSname;
Process proc= null;
WebServicesXML xml;
WSthread(String name){
WSname=name;
}
public void run() {
try {
//my code
// Run a java app in a separate system process
String cmd = (WSname);
proc = Runtime.getRuntime().exec("java -jar "+cmd);
xml = new WebServicesXML();
//Process proc = Runtime.getRuntime().exec("java -jar .jar");
// Then retreive the process output
//InputStream in = proc.getInputStream();
//InputStream err = proc.getErrorStream();
BufferedReader is = new BufferedReader(new InputStreamReader(proc.getInputStream()));
String line;
String regex = "\\bhttp\\b";
Pattern pattern = Pattern.compile(regex);
String WSaddress = "";
while ((line = is.readLine()) != null){
Matcher matcher = pattern.matcher(line);
if(matcher.find()){
WSaddress = line;
System.out.println("Updating WS address..."+WSaddress);
xml.create(WSname, WSaddress);
}
System.out.println(line);
}
}catch(Exception e){
System.out.println(e.getMessage());
}
}
public void close(){
proc.destroy();
}
public class WebServicesXML{
public int totalWebServices;
public String WSnamelist[];
public synchronized void create(String WSname, String WSaddress) throws OException, TransformerConfigurationException, TransformerException, ParserConfigurationException{
try {
DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
Document readdoc = docBuilder.parse("webservices.xml");
// normalize text representation
readdoc.getDocumentElement ().normalize ();
Node rootList = readdoc.getDocumentElement();
Element rootElement = (Element)rootList;
Element webservice = readdoc.createElement("WebService");
Element name = readdoc.createElement("name");
Element address = readdoc.createElement("address");
name.setTextContent(WSname);
address.setTextContent(WSaddress);
webservice.appendChild(name);
webservice.appendChild(address);
rootElement.appendChild(webservice);
/////////////////
//Output the XML
//set up a transformer
TransformerFactory transfac = TransformerFactory.newInstance();
Transformer trans = transfac.newTransformer();
trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
trans.setOutputProperty(OutputKeys.INDENT, "yes");
//create string from xml tree
File file = new File("webservices.xml");
StringWriter sw = new StringWriter();
StreamResult result = new StreamResult(file);
DOMSource source = new DOMSource(readdoc);
trans.transform(source, result);
}
catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TransformerConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TransformerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
WebServicesXML.java
public class WSthread extends Thread {
public String WSname;
Process proc= null;
WebServicesXML xml;
WSthread(String name){
WSname=name;
}
public void run() {
try {
//my code
// Run a java app in a separate system process
String cmd = (WSname);
proc = Runtime.getRuntime().exec("java -jar "+cmd);
xml = new WebServicesXML();
//Process proc = Runtime.getRuntime().exec("java -jar .jar");
// Then retreive the process output
//InputStream in = proc.getInputStream();
//InputStream err = proc.getErrorStream();
BufferedReader is = new BufferedReader(new InputStreamReader(proc.getInputStream()));
String line;
String regex = "\\bhttp\\b";
Pattern pattern = Pattern.compile(regex);
String WSaddress = "";
while ((line = is.readLine()) != null){
Matcher matcher = pattern.matcher(line);
if(matcher.find()){
WSaddress = line;
System.out.println("Updating WS address..."+WSaddress);
xml.create(WSname, WSaddress);
}
System.out.println(line);
}
}catch(Exception e){
System.out.println(e.getMessage());
}
}
public void close(){
proc.destroy();
}
public class WebServicesXML{
public int totalWebServices;
public String WSnamelist[];
public synchronized void create(String WSname, String WSaddress) throws OException, TransformerConfigurationException, TransformerException, ParserConfigurationException{
try {
DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
Document readdoc = docBuilder.parse("webservices.xml");
// normalize text representation
readdoc.getDocumentElement ().normalize ();
Node rootList = readdoc.getDocumentElement();
Element rootElement = (Element)rootList;
Element webservice = readdoc.createElement("WebService");
Element name = readdoc.createElement("name");
Element address = readdoc.createElement("address");
name.setTextContent(WSname);
address.setTextContent(WSaddress);
webservice.appendChild(name);
webservice.appendChild(address);
rootElement.appendChild(webservice);
/////////////////
//Output the XML
//set up a transformer
TransformerFactory transfac = TransformerFactory.newInstance();
Transformer trans = transfac.newTransformer();
trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
trans.setOutputProperty(OutputKeys.INDENT, "yes");
//create string from xml tree
File file = new File("webservices.xml");
StringWriter sw = new StringWriter();
StreamResult result = new StreamResult(file);
DOMSource source = new DOMSource(readdoc);
trans.transform(source, result);
}
catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TransformerConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TransformerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
您需要确保在任何时候只有一个线程在访问该文件。您可以使用可用的本机同步工具(如
synchronized
关键字和/机制),也可以查看更高级别的同步工具,如或。您需要确保在任何时候只有一个线程访问该文件。您可以使用可用于此目的的本机同步工具(例如synchronized
关键字和/机制),也可以查看更高级别的同步工具,例如或。同步方法时,锁定对象(对于非静态方法)因此,因为每个线程都有自己的WebServicesXML
实例,所以每个线程都可以获得一个锁,并且不会发生阻塞
处理此问题的最简单方法是只创建WebServicesXML
的单个实例,并在创建该实例时将其传递给每个线程
或者在WebServicesXML
中创建一个信号量对象,如下所示:
private static final Object FILE_SEMAPHORE = new Object();
synchronized (FILE_SEMAPHORE) {
//File update code goes here.
}
然后在更新文件的行周围添加一个同步块,如下所示:
private static final Object FILE_SEMAPHORE = new Object();
synchronized (FILE_SEMAPHORE) {
//File update code goes here.
}
当您同步一个方法时,锁定对象(对于非静态方法),因为每个线程都有自己的
WebServicesXML
实例,所以每个线程都可以获得一个锁定,并且不会发生阻塞
处理此问题的最简单方法是只创建WebServicesXML
的单个实例,并在创建该实例时将其传递给每个线程
或者在WebServicesXML
中创建一个信号量对象,如下所示:
private static final Object FILE_SEMAPHORE = new Object();
synchronized (FILE_SEMAPHORE) {
//File update code goes here.
}
然后在更新文件的行周围添加一个同步块,如下所示:
private static final Object FILE_SEMAPHORE = new Object();
synchronized (FILE_SEMAPHORE) {
//File update code goes here.
}
基本问题是在每个线程中构建单独的DOM,以便应用单个转换。这意味着最后一个运行的线程在将其内容写回XML文件方面“获胜” 一方面,我假设您使用线程是为了提高性能,但另一方面,您需要多次解析和序列化XML。线程实现是不安全的 我的建议是删除线程并在循环中进行更改。当它工作时,您可以测量性能,然后选择查看使用线程的实现
记住,过早优化是万恶之源。基本问题是在每个线程中构建单独的DOM,以便应用单个转换。这意味着最后一个运行的线程在将其内容写回XML文件方面“获胜” 一方面,我假设您使用线程是为了提高性能,但另一方面,您需要多次解析和序列化XML。线程实现是不安全的 我的建议是删除线程并在循环中进行更改。当它工作时,您可以测量性能,然后选择查看使用线程的实现
记住,过早优化是万恶之源。感谢您的回复。为了消除线程声音问题,我的程序需要执行子进程的动态编号并监视子进程。有什么好主意吗?您有多个子进程可能需要修改文件系统上的同一个XML文件?在这种情况下,请使用锁定文件模式同步对该文件的访问。感谢您的回复。为了消除线程声音问题,我的程序需要执行子进程的动态编号并监视子进程。有什么好主意吗?您有多个子进程可能需要修改文件系统上的同一个XML文件?在这种情况下,请使用锁定文件模式同步对文件的访问。