tomcat-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From PSA <po...@posom.com>
Subject Re: Thread-safety
Date Fri, 26 Jan 2001 18:34:47 GMT
Pier Fumagalli wrote:
> 
> Luc Vanlerberghe <lvl@bvdep.com> wrote:
> 
> > Thanks for incorporating this change to jasper.  I had suggested it a
> > couple of months ago (22/11/2000 in fact: see
> > http://w6.metronet.com/~wjm/tomcat/2000/Nov/msg00747.html)
> >
> > In the meantime, however, I have been browsing through the sessions of
> > the JavaOne conference of 2000 and there's (at least) one session of
> > particular interest: "Correct and Efficient Synchronization of Threads
> > in the Java Programming Environment" (The complete list including links
> > to realAudio recordings is on
> > http://java.sun.com/javaone/javaone00/replay.html)
> > Here's a direct link to the abstract:
> > http://jsp.java.sun.com/javaone/javaone2000/event.jsp?eventId=754
> >
> > One of the points that is made in that session is that even this
> > 'double-check idiom' is NOT thread-safe!
> > The exact reasons for this are not so easy to understand but basically
> > what I understood is that within the synchronized block, writes to main
> > memory can occur in any order, meaning that the value of _jspx_inited
> > can be commited to main memory while some of the results of the
> > initialisation code are still in e.g. processor registers.  When the
> > thread exits the synchonized block, it is required to commit all its
> > changes to main memory, but if another processor checks the value of
> > _jspx_inited *before* acquiring the lock, it may see _jspx_inited being
> > true while not all other initialisation data has actually been written
> > to main memory.
> > For more details, please follow the links above...
> 
> GOTCHA! I was looking at your post with Justy this afternoon and didn't
> understand why it's not "threadsafe"... What she committed (without the ugly
> writer.println() stuff is:
> 
> if (_jspx_inited == false) {
>     synchronized (this) {
>         if (_jspx_inited == false) {
>             _jspx_init();
>             _jspx_inited = true;
>         }
>     }
> }
> 
> So, if the commit of the _jspx_inited value can occour while _jspx_init() is
> still in progress (let's imagine some weird code optimization techniques),
> to fix this bug, we should simply remove the first line of the commit and
> simply write:
> 
> synchronized (this) {
>     if (_jspx_inited == false) {
>         _jspx_init();
>         _jspx_inited = true;
>     }
> }
> 
> So that, no matter what happens, a thread must ALWAYS acquire a lock on the
> synchronized piece of code, and so we are guaranteed that _jspx_init() is
> called at least once all the time...

If even this is thread-safe, you have now required that all requests
block and aquire a lock at this point.  The idea of the removed test was
to prevent this necessity after the first access.

As Luc asked, why can't this code be optimized into init()?

-Paul

Mime
View raw message