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