"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]

Reply via email to