"ES" <ruby-ml / magical-cat.org> schrieb im Newsbeitrag
news:40904.192.152.100.150.1109540981.squirrel / webmail.bidwell.textdrive.com...
> On Sun, February 27, 2005 10:44 am, Csaba Henk said:
> > On 2005-02-27, Yohanes Santoso
<ysantoso-rubytalk / dessyku.is-a-geek.org>
> > wrote:
> >> Csaba Henk <csaba / phony_for_avoiding_spam.org> writes:
> >>
> >>> Is "$a ||= 1" thread safe? I'd guess so, as "||=" is one piece of
> >>
> >> It is not guaranteed to be thread-safe, although in current official
> >> ruby vm it is 'atomic'.
> >
> > So that means it thread safe now, but it's not guaranteed to stay so?
> > Is there a real chance/reason to make it non-atomic (either during the
> > development of the current implementation, or in a new implementation
> >
> > Then how to do the following: I need a method which inserts an element
> > into an array, named by an instance variable. The variable is possibly
> > undefined. I want to make it thread-safe. The best I came up with is
> >
> >   @a ||= []
> >   @a << foo
> >
> > which then thread-safe by the current implementation, but not
guaranteed
> > to stay so...
> >
> > Note that I can't do "@a = []" in #initialize (as the code lies within
a
> > block passed to #define_method within an instance method definition of
> > Module itself; so it's not just a simple static method definition for
a
> > certain class).
> >
> > If I had @mutex,
> >
> >   @mutex.synchronize { @a ||= [] }
> >   @a << foo
> >
> > would do the job perfectly; but having @mutex is exactly the same
> > problem as having @a ...
> >
> > Having @@mutex in the class would be fine as far as thread safety
goes, but
> > then all instances would use that same @@mutex on each call,
absolutely
> > unnecessarily after the first time... Maybe
>
> Just answering to this point: there's a trick called the double-checked
> locking pattern that avoids the unnecessary lock. I'm not sure if it
helps
> any in your situation:
>
> @@mutex.synchronize {@a ||= [] unless @a} unless @a

There is one test too much.  I'm sure you wanted this:

@@mutex.synchronize {@a ||= []} unless @a

It might work in Ruby, but it doesn't in other languages - Java for
example.  I'd rather not use it as it makes code more complicated.  Use
this only if you have a serious performance problem.  Even then I'm not
sure whether the difference is big enough to matter.  Plus, you might run
into the same problems as with double checked locking on Java when Ruby
runs on different platforms (a JVM for example using native threads).

Kind regards

    robert