• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

nodeList.item(0); NPE in multithreaded environment.

 
Ranch Hand
Posts: 133
Hibernate Oracle Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi,

I am having a problem occuring while executing XPathAPI operation, in a multithreaded environment.

While excuting where is org.w3c.dom Nodelist,
something strange is happening.

I am trying to get nodes form an XML document (a bit complex document).

returns an object for most of the times, but when there are many threads, trying to get nodes from the XML document, it throws NullPointerException.

However if I catch the exception and perform the same operation again, it works.

The piece of code I am using is as below,



Here the line,

"Item received in second attempt from NodeList in Catch" gets printed a few times when run with 20 prallel threads.

I am trying to find answers to some questions here,

1) When comes out to be TRUE, should there be an exception while executing ?

2) Why the operations works in second attempt?

3) do I need to further check the implementation that is being used by JAVA6?

Pease help me in finding the answers, also let me know if I am overlooking some aspect.

P.S.

This topic might be a bit inapopropriate for this forum.

But as this is occuring with multithreaded code only, I am posting it here.

Many Thanks,
Rohit
 
Bartender
Posts: 4179
22
IntelliJ IDE Python Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The NodList API (and the org.w3c.dom package API) don't say anything about thread safety, so in the absence of saying they are thread safe, you should assume they are not. That means you should properly synchronize access to the Document, the Nodes and the NodeList so no two threads can access the data at the same time. If you need simultaneous access I would suggest giving each thread a different instance of the document, nod, and NodeList so they don't interfere with each other.
 
rohit chavan
Ranch Hand
Posts: 133
Hibernate Oracle Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello Steve,

Thanks for the reply.

The document is being parsed only once per thread. (which we can call as set() operation)

I changed the get() operation to cover it with synchronized block,

However, the number of times NPE was being thrown has come down drastically , still it can be seen for a couple of times during a test execution. (with same number of threads i.e. 20)

and it still works in the second attempt.

I am further checking if this has anything to do with the heap-space settings, though I am not getting any out-of-memory error, I wonder if this can be the reason.

Still finding the answers.
 
Steve Luke
Bartender
Posts: 4179
22
IntelliJ IDE Python Java
  • Likes 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

rohit chavan wrote:The document is being parsed only once per thread. (which we can call as set() operation)


Unfortunately, you can't assume the state of the document is not being modified by each thread. It is not safe, I don't think, to read the document once, and share it with multiple threads, as it is the root of all searches, and therefore the root of all NodeLists. You need to put this 'set' operation into a synchronized block that would synchronize with all the NodeLists. In fact, I would probably use the Document as the object which I synchronize on, regardless of the number of NodeLists that exist, since that represents the data which needs to be protected. And every chunk of code which accesses the Document, a Node, or the NodeList will synchronize on the Document.

I am further checking if this has anything to do with the heap-space settings, though I am not getting any out-of-memory error, I wonder if this can be the reason.


I doubt it. What is most likely happening is that multiple different threads are sharing the same reference (probably in the Document instance) to the 'current' or 'root' node. Traversing a list probably modifies this value, and when some other thread tries to access the reference while a different thread is in the process of modifying it. I would expect that even when you don't get the null pointer exception you probably get several cases where the value you do get is not correct (but it is probably harder to detect because of no exception). If you want to use the same document and its data in multiple threads I think you should create a very robust testing scheme where you can detect when incorrect values are retrieved.
 
rohit chavan
Ranch Hand
Posts: 133
Hibernate Oracle Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

It is an XML document which is changed once in a while with necessarily a server restart.

And it is not modified by any of the threads. (it is like a read-only document)

So the concurrent reads is what I think, I need to concentrate on.

I agree with your view on reference modification, will dig further into it.

Steve Luke wrote: If you want to use the same document and its data in multiple threads I think you should create a very robust testing scheme where you can detect when incorrect values are retrieved.



Will check and change the test environment , and post if there are any findings.

Many Thanks, Steve.

 
Author and all-around good cowpoke
Posts: 13078
6
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I would certainly be using the getLength() method of NodeList - when it indicates an empty list you can investigate. Much preferable to looking at an NPE.

Bill
 
Steve Luke
Bartender
Posts: 4179
22
IntelliJ IDE Python Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

William Brogden wrote:I would certainly be using the getLength() method of NodeList - when it indicates an empty list you can investigate. Much preferable to looking at an NPE.

Bill


He actually is doing that, but there is an inconsistency, he gets a length > 0, but still gets an NPE, and if he tries a second time, doesn't get the NPE. This inconsistency is what makes me believe he is still not synchronizing all the access correctly, or he would be better off with copies of the document, rather than multiple views of a single instance.
 
rohit chavan
Ranch Hand
Posts: 133
Hibernate Oracle Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank you Steve,
Thank you Bill,

Steve Luke wrote:
This inconsistency is what makes me believe he is still not synchronizing all the access correctly, or he would be better off with copies of the document, rather than multiple views of a single instance.



Making the access (read) synchronous is taking a hit on performance, which is obvious.

So I am trying to create copies of the document object. I think using commons pool should be my obvious choice.

Or am I misreading my requirement here, and just making a certain copies of the currently singleton document object should be my first concern.

I would be surely doing the testing for both the approaches.

Meanwhile, please help me in case there can be a better approach.
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
reply
    Bookmark Topic Watch Topic
  • New Topic