[
https://issues.apache.org/jira/browse/XMLBEANS-345?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12582856#action_12582856
]
Radu Preotiuc-Pietro commented on XMLBEANS-345:
-----------------------------------------------
I have tried your test code with my own Schema and a similar-sized document. I
have also inspected the code visually; these are my findings:
First of all, the code looks correct: everything is synchronized and GlobalLock
is called in the expected pattern, nothing I could detect that might go wrong.
Looking at the test code, what it does basically is continuous sets of the same
XmlObject to a parent XmlObject on 20 threads and each thread prints out a "."
every 10,000 sets. After 10 seconds, a full stacktrace of all the threads is
printed to the console.
But the thing is that doing 10,000 sets of a complex document takes time.
Moreover, since the threads are blocked on the GlobalLock for most of the time
and work in paralel, initially only one or two threads hit the mark before 10
seconds have elapsed and so you don't see a lot of dots. Then, when the
stacktraces are printed, all of the threads are indeed blocked waiting for the
GlobalLock *except* for two (on my dual-core proc, I suspect on single-core
procs only one is unblocked) which are performing work. Increasing the time
yields more "."s but the same stacktraces at the end.
So I don't think we are dealing with a deadlock at all, merely with the fact
that, not able to run all the threads at the same time, the JVM suspends all
threads except for one or two on the GlobalLock call. I have tried this with
Sun's JVM and with JRockit and the results are the same, except for the fact
that JRockit's synchronization overhead is smaller, so you get more sets done
than with HotSpot in the same amount of time.
I am going to resolve this issue. While the test case proves that there is
contention, it doesn't prove that there is a deadlock.
> 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]