MRI is a steaming pile. (Note: You're not allowed to disagree with this unless you're a C programmer that's spent some quality time with MRI's code.) It seriously shook my faith in Ruby the first time I had to dive into MRI's code: "Could someone who waxes poetic about elegance and fun in coding really produce something this fugly? Does Matz have any idea what he's talking about?" Rubinius has a sane design and is a pretty clean base to build a Ruby implementation with some staying power on. I basically see Rubinius as the rewrite that MRI was going to have to have at some point.
That said, at present, I still use MRI. I try Rubinius every couple months to see how it's progressed performance-wise for the cases that I care about, and while it's not there yet, this seems to be mostly a matter of time.
That said, I think rbx is the way forward too.
There is a massive amount of bad code on the intertubes that has been around for decades, and I kind of hope we will not be programming in ruby when it's 40 years old.
a) The ruby standard library is written in Ruby and is actually surprisingly well-behaved from a threading perspective. The code is not super-pretty, but it uses appropriate locking strategies and has been well-tested in threaded environments. All three major implementations (JRuby, MRI and Rubinius) share the vast majority of the Ruby standard library, so if JRuby works, Rubinius will work.
2) For the part of MRI written in C (which Rubinius calls the "kernel"), Rubinius has reimplemented the entire thing mostly in Ruby with some primitives. Since they own that code, it is their responsibility to define its semantics when run in parallel.
3) Rubinius implements its locking classes (like Mutex and ConditionVariable, see https://github.com/evanphx/rubinius/blob/master/lib/thread.r...) on top of its own low-level Channel implementation (see https://github.com/evanphx/rubinius/blob/master/kernel/boots...), which can be used to implement more sophisticated locking strategies. They have been working on this for a long time, and have been planning for it even longer.
Since rubinius provides the same C-api ruby does (ignoring FFI for now) wouldn't all the accesses to external libraries need to be wrapped in a shared big lock?