You really shouldn't be relying on globals anyway. Using $1 etc. is a serious code smell. It shouldn't by definition be threadsafe in any event. The only way that would work would be if you rely on the threads not actually running at the same time as an implementation detail of the MRI.
def f
p $~ # => nil
"123" =~ /\w+/
p $~ # => #<MatchData "123">
end
p $~ # => nil
"abc" =~ /\w+/
p $~ # => #<MatchData "abc">
f
p $~ # => #<MatchData "abc">
Matz himself has said he regrets putting these variables in the language, and some day they may disappear. We'll match behavior as much as possible, but they're a relic no matter how you slice it.
Well, it's fair to say "it works in MRI"; $1 being frame-local and thread-local is an exception to the rule, but it is How It Works. JRuby should behave similarly, full stop.
They're what MRI calls "svars", or special variables. They're thread and scope-local, and regardless of your feelings towards them, they're still used all over the place, in old and new code alike.