When I've written multithreaded code in Ruby in the past I've been quite
diligent about synchronizing access to shared resources.  However, now I'm
working on a project where oversynchronization may actually be costly and
I'm curious about how much I can actually do with core datastructures
before running into thread safety issues.

I've seen the issue of thread safety come up a couple times on the list
before but I've not been able to find concrete answers as to what exactly
is safe.

Thus, a few questions:

1.  Will Hash#[] always return either a previously assigned value, or the
    default value, despite interleaved calls to Hash#[]= and Hash#delete?

    Or is it possible for Hash#[] in such a scenario to result in a wild
    pointer access that would raise an exception or worse?

2.  Will interleaved calls to Hash#[]= do something sensible?  That is,
    when all interleaved calls are finished, will a lookup always return
    one of the previously assigned values (even if it's not the most
    "recent")?

3.  Can something "bad" happen when a hash is modified during execution of
    Hash#each?  I understand that such a call may yield elements that
    were added since the start of its execution, or may not yield elements
    that were delete since the start of its execution.  But, at least, will
    all key/value pairs be yielded that weren't modified during execution?

    Will each pair be yielded only once?  I'm thinking a rehash during #each
    could result in disaster.

4.  In general, can the lack of Ruby-level synchronization actually corrupt
    a datastructure in some really unfortunate way?  For example, could
    interfering mutations to middle elements of an array accidentally lop
    off the entire end of an array?

5.  Does the answer to any of the above change for ruby 1.9?

Basically, in short, I'm willing to give up synchronized access to data
structures for trivial operations (i.e., lookups) where the result is only
valid for an infinitessimally short peiord anyways, so long as I know that
it won't result in wild application behavior like exceptions or a segfault.

A semi-related question:  Are there readers/writers locks for Ruby?  I've
not seen one.

Thanks!