0 Replies Latest reply on May 17, 2006 10:27 AM by Branden Smith

    JBossMQ threads sharing locally-instantiated objects?

    Branden Smith Newbie

      I have implemented a JBossMQ-driven JMS Queue which is answered by a JBoss-managed pool of Message-Driven Beans; the deployment descriptor allows the MDB to run in as many as 15 threads simultaneously, so there are usually multiple instances of onMessage() running at once.

      The problem which I'm having is that objects instantiated by onMessage in one thread appear to be allocated to memory shared with the equivalent object in another thread, causing data collision problems which would normally be associated with data race conditions. My onMessage code looks something like this:

      public void onMessage(Message inMessage) {
       XMLComboObject generator;
      
       ...
      
       generator = new XMLComboObject();
      


      XMLComboObject is a custom class which contains multiple instances of XMLTag, another class I wrote to represent the structure of an XML tree. Each one of these is a very large object, so any given instance of XMLComboObject consumes a sizeable amount of memory.

      XMLTag contains a method called replaceContents(String tagName, String newContents) which deletes the current contents of an XML tag withing the object and replaces them with the new String:

      ...
      replaceContents(String tagName, String newContents) {
       deleteContents(tagName);
       addContents(tagName, newContents);
      }
      ...
      


      All of the sources I've read about Java threads indicate that local variables are inherently thread-safe, as they are allocated on the stack, which is not shared among threads. However, when I try to dump the contents of the XML tag from an XMLComboObject associated with one thread, I frequently (but erratically) find that the values contained within a tag are concatenated with values which should be associated with another thread. So where I should see:

      THREAD ONE VALUES
      ...
      AAAAA
      ...

      THREAD TWO VALUES
      ...
      BBBBB
      ...

      I often see:

      THREAD ONE VALUES
      ...
      AAAAABBBBB
      ...

      THREAD TWO VALUES
      ...
      AAAAABBBBB
      ...

      The only thing I can think of which could be happening here is that both threads are running replaceContents simultaneously on the same XMLTag object, and thus encountering a race condition. This should never be the case, however, since the XMLTags in question are subordinate to a local variable within onMessage(), which is (to the best of my understanding) assumed NOT to be shared among threads.

      So is there any way that Java could be attempting to re-use local instances of the objects that I'm instantiating, and in the process sharing memory which needs to be local to a given JMS thread? I can't find any documentation for such a behavior, but it's the only possibility which is coming to mind.

      I don't know whether this is a JVM problem (in terms of memory allocation) or a JBossMQ problem (in terms of thread management). I am running JBoss 4.0.3-SP1 on Java 1.4.2_07-b03.

      Thanks,

      Branden Smith

      (I have also posted this question on the Sun Java Forums: http://forum.java.sun.com/thread.jspa?threadID=736921&tstart=0.)