"tony summerfelt" <snowzone5 / hotmail.com> schrieb im Newsbeitrag
news:cajqf0trmr26t845682he50t20gep9dhlu / 4ax.com...
> On Wed, 21 Jul 2004 01:20:56 +0900, you wrote:
>
> >The methods inside them can be called concurrently from multiple
> >threads.
>
> >Note that this is not the same as reentrant, where the same method can
> >be safely executing simultaneously in two threads.
>
> when i first read this i thought ok, that answers my question...but
> after over thinking it,  i'm not sure i see the difference.
>
> i would think the same  method  running in two different threads is
> either safely executing or it isn't.
>
> >Thread safety can be implemented easily by adding the appropriate
> >mutexes.  Making a module reentrant requires more care.
>
> i've gone to considerably length to make sure methods in my module are
> thread safe as they access the same resource.
>
> i've leaned on them
> pretty heavily, with threaded code and the resource never gets
> corrupted..

That's not a proof - at best it's an indication. :-)

> just wanted to make sure i was on the right track...

There are several ways to achieve thread safety.  Making methods reentrant
is one of them.  Consider

class Foo
  def bar(x,y)
    # this method is thread safe because it does
    # not access any instance state
    ( x + y ) * 2
  end
end

You can invoke this method arbitrarily often from multiple threads.
Synchronizing with mutexes is another way to make method thread safe.
Thread confinement is another: you make sure that an instance is just
accessible from a single thread, like in:

10.times do |i|
  Thread.new(i) do |limit|
    storage = []
    # accesses to storage need not be synchronized because
    # there is one per thread and the reference is not leaked
    # to other threads
    limit.times { storage << "x" }
    puts storage.join
  end
end

You can as well consider not to put synchronization / mutexes in a class at
all but instead rely on external synchronization.  In some cases this is
even necessary:

storage = {}
lock = Mutex.new

10.times do |i|
  Thread.new( "Thread-#{i}" ) do |name|
    key = rand 10

    lock.synchronize do
       if not storage.has_key? key
          storage[key] = []
       end

       storage[key] << name
    end

    sleep( rand(5) )
  end
end

This is typically the case if you have to do multiple accesses to a resource
that depend on each other.  In this case the hash insertion depends on the
check for key presence.

Regards

    robert