> Does this mean that the following code would be thread safe?
NO, it's not!
Check the JavaOne session I mentioned and follow the links they gave.
There have been various patches suggested, but most of them are wrong...
The only safe way to do it is synchronize before the first test...
The reason your construct might fail is that the JLS does not allow
statements to be moved out of a synchronized block, but it is allowed to
move statements into such a block (with certain restrictions)...
So the _jspx_inited = true can be legally moved into the second
synchronized block and then moved around within it again according to
what the compiler/memory-subsysytem thinks best to optimize for speed.
It may work on 99% of all systems/compiler combinations, but Murphy's
law says that chances are still 50/50 it will fail once in a while on
your system while the boss is watching :)
These optimizations were explicitly allowed in the JL/JVM spec to allow
for speed optimizations in the compilers/JVMs/multiprocessing hardware.
Again, for more info, follow the links from the session for more info...
http://w6.metronet.com/~wjm/tomcat/2000/Nov/msg00747.html)
http://java.sun.com/javaone/javaone00/replay.html)
http://jsp.java.sun.com/javaone/javaone2000/event.jsp?eventId=754
Luc Vanlerberghe
Ethan Wallwork wrote:
>
> "When the thread exits the synchonized block, it is required to commit all its
> changes to main memory"
>
> Does this mean that the following code would be thread safe?
>
> if (_jspx_inited == false) {
> synchronized (this) {
> if (_jspx_inited == false) {
> synchronized(new Object()) {_jspx_init();}
> _jspx_inited = true;
> }
> }
> }
>
> The inner synchronized block should ensure that the initialization gets
> commited before _jpsx_inited gets set to true.
>
> Fun stuff!
>
> --
> Ethan
>
> -----Original Message-----
> From: Pier Fumagalli [mailto:[EMAIL PROTECTED]]
> Sent: Friday, January 26, 2001 5:03 AM
> To: [EMAIL PROTECTED]
> Cc: Justyna Horwat
> Subject: Re: Thread-safety
>
> Luc Vanlerberghe <[EMAIL PROTECTED]> 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...
>
> Yep, makes sense...
>
> Pier
>
> --
> Pier Fumagalli <mailto:[EMAIL PROTECTED]>
> I'm selling my Sony Vaio Z505. Check out <http://www.betaversion.org/~pier/>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, email: [EMAIL PROTECTED]
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, email: [EMAIL PROTECTED]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, email: [EMAIL PROTECTED]