Note:下面显示的代码摘要是not我遇到问题的代码的精炼。因为其他人已经回答了,所以我将原始摘要留在这里,但是actual代码显示在我下面提供的答案中。
我无法将其与一个小的失败测试用例隔离,但我在以下一般构造中遇到了失败:
class Foo
@mutex = Mutex.new
....
def self.bar
@mutex.synchronize { ... }
end
end
如果我创建多个线程调用Foo.bar
, 有时@mutex
将评估为nil
in bar
。如果我使用常量(例如 MUTEX)而不是实例变量,则不会出现此问题。
我不知道这是否重要,但我在多核机器上运行 JRuby。
我希望得到有关如何隔离问题的任何解释或帮助。
更新:我相信这与自动加载有关。使用 Rails,我能够通过以下内容重现类似的问题foo.rb
在 Rails 自动加载的目录之一中:
class Foo
@mutex = Mutex.new
def self.bar
@mutex.synchronize {}
end
end
当我在 Rails 控制台中执行以下命令时:
1.upto(4).map { Thread.new { Foo.bar }}.map(&:join)
我收到以下错误:
RuntimeError: Circular dependency detected while autoloading constant Foo
from /Users/palfvin/.rvm/gems/jruby-1.7.10@javlats/gems/activesupport-4.0.1/lib/active_support/dependencies.rb:461:in `load_missing_constant'
from /Users/palfvin/.rvm/gems/jruby-1.7.10@javlats/gems/activesupport-4.0.1/lib/active_support/dependencies.rb:184:in `const_missing'
from (irb):1:in `evaluate'
这种行为在 CRuby (MRI Ruby) 中是相同的。