Wes Wannemacher wrote:
One issue findbugs points out is that the BackgroundProcess constructor
starts it's thread before returning, which means that any subclass won't
get to finish it's constructor before the thread is started.  This is
relevant to the solution offered at
http://cwiki.apache.org/WW/hibernateandspringenabledexecuteandwaitintercept
or.html and I'm not sure if it's really an issue or how to fix it (but I'm
interested since I use something like that in my current project :-).

I'm looking at BackgroundProcess and it looks like the only thing that happens after .start() is some exception handling logic... I'm not sure as I haven't had to deal with multithreading issues for a long time (and I don't even think I was using Java the last time I had to think about it). But, it doesn't seem like a real issue to me. Of course, I'd concede if someone more fluent jumped in and pointed out that I'm wrong.

After looking at this a bit more I believe that the struts2 code is correct, but that OpenSessionBackgroundProcess on that wiki page has a race condition. The problem is that the constructor of this object starts another thread that immediately starts interacting with this object, potentially before this object's constructor is even done running. As you said, t.start() is the last thing that happens in the constructor of BackgroundProcess, but the one line left in the constructor of OpenSessionBackgroundProcess is recording a useful piece of information (sessionFactory) that is assumed to already be set at the beginning of beforeInvocation(), but might not be set yet when beforeInvocation is invoked.

I believe the dumb fix is as simple as adding a member "initialized" to OpenSessionBackgroundProcess that starts at false and is set to true as the new last line of OpenSessionBackgroundProcesssessionFactory's constructor, and adding a busy-wait loop at the beginning of beforeInvocation() that calls Thread.yield() until the initialized field goes true. I'm certain that there's a better solution than a busy-wait loop, but it's past my bed time, so I'll think about that more in the morning. The obvious solution (synchronized methods) won't work to avoid simultaneous execution of both the constructor and beforeInvocation, because a constructor cannot be synchronized.

-Dale

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@struts.apache.org
For additional commands, e-mail: dev-h...@struts.apache.org

Reply via email to