Setting the same variable to multiple properties in multi-threaded environment
causes deadlocking
-------------------------------------------------------------------------------------------------
Key: XMLBEANS-345
URL: https://issues.apache.org/jira/browse/XMLBEANS-345
Project: XMLBeans
Issue Type: Bug
Components: XmlObject
Affects Versions: Version 2.3, Version 2.3.1
Environment: Microsoft Windows XP [Version 5.1.2600], single-core
java version "1.5.0_10"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_10-b03)
Java HotSpot(TM) Client VM (build 1.5.0_10-b03, mixed mode)
Reporter: Ian Sollars
Priority: Critical
When setting a property on many XmlBeans objects with a single large variable,
all threads concerned will block with this stacktrace:
java.lang.Object.wait:-2
java.lang.Object.wait:-1
org.apache.xmlbeans.impl.common.Mutex.acquire:33
org.apache.xmlbeans.impl.common.GlobalLock.acquire:27
org.apache.xmlbeans.impl.values.XmlObjectBase.set:1944
The test below sets a Type on it's Document and illustrates the problem. I
can't publish the actual schema and namespace, but to give an idea of size, the
XML object is about 90 KB of complex data (multiple namespaces, hundreds of
elements, embedded CDATA).
A workaround has been included in commented-out form.
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.xmlbeans.XmlException;
import tests.LargeDataStructureType;
import tests.LargeDataStructureDocument;
public class BlockingExample {
public static void main(String[] args) throws InterruptedException,
XmlException, IOException {
LargeDataStructureDocument doc =
LargeDataStructureDocument.Factory.parse(new File("exampleFile.xml"));
LargeDataStructureType type = doc.getLargeDataStructureType();
List<Setter> setters = new ArrayList<Setter>();
for(int i = 0; i != 20; i++) setters.add(new Setter(key));
for(Setter s : setters) s.start();
Thread.sleep(10000);
Map<Thread,StackTraceElement[]> map=Thread.getAllStackTraces();
for(Thread t:map.keySet()){
StackTraceElement[] ss=map.get(t);
System.out.println("Thread:"+t.getName()+":"+t.getState()+":"+t.isAlive());
if(ss!=null) {
for(StackTraceElement s:ss){
System.out.println("\t"+s.getClassName()+"."+s.getMethodName()+":"+s.getLineNumber());
}
}
}
System.exit(0);
}
}
class Setter extends Thread {
private static int counter = 0;
private LargeDataStructureType type;
Setter(LargeDataStructureType type) {
/*
* This reproduces the behaviour
*/
this.type = type;
/*
* This also reproduces the behaviour
*/
// this.type = (LargeDataStructureType)type.copy();
/*
* This is a reliable workaround.
*/
// this.type = LargeDataStructureType.Factory.newInstance();
// type.set(type);
}
public void run() {
while(true) {
LargeDataStructureDocument obj =
LargeDataStructureDocument.Factory.newInstance();
obj.setLargeDataStructure(key);
if(counter++ % 10000 == 0) {
System.out.print(".");
}
}
}
}
This produces the following output:
.Thread:Thread-7:WAITING:true
java.lang.Object.wait:-2
java.lang.Object.wait:-1
org.apache.xmlbeans.impl.common.Mutex.acquire:33
org.apache.xmlbeans.impl.common.GlobalLock.acquire:27
org.apache.xmlbeans.impl.values.XmlObjectBase.set:1944
tests.LargeDataStructureTypeImpl.setLargeDataStructure:xx
be.inglease.wel.Setter.run:64
Thread:Thread-13:WAITING:true
java.lang.Object.wait:-2
java.lang.Object.wait:-1
org.apache.xmlbeans.impl.common.Mutex.acquire:33
org.apache.xmlbeans.impl.common.GlobalLock.acquire:27
org.apache.xmlbeans.impl.values.XmlObjectBase.set:1944
tests.LargeDataStructureTypeImpl.setLargeDataStructure:xx
be.inglease.wel.Setter.run:64
(...etc. for 20 threads)
The expected output would just be lots of dots followed by various stacktraces.
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]