双重检查锁定在Ruby中安全吗?

Rea*_*nly 3 ruby concurrency

文章指出,双重检查锁定是在特定的语言/硬件组合不安全时共享变量可以与到仅部分初始化的对象的引用被更新。

我在想:这是否也适用于Ruby?这是否因运行平台上的Ruby实现而有所不同,还是语言规范中详细说明了正确的行为?

Hon*_*gli 5

Java中的双重检查很危险,因为可能在构造函数实际完成之前将值分配给变量。这在Ruby中不会发生:构造对象与将函数调用的结果分配给变量是相同的,因为构造函数只是普通的函数。仅在构造函数完全完成后才进行分配。

在MRI上,分配是原子的。尚无正式的Ruby语言或内存模型规范,但其他实现往往会尝试模仿MRI的行为,甚至是最晦涩的细节。赋值语句的原子性是一个相当重要的行为,因此我希望其他Ruby实现的赋值也是原子的。

如果您不介意在争用过程中意外地构造两个对象,并且一个对象由于重复而在以后被垃圾回收,则可以使用|| =运算符,如下所示:

@singleton ||= FooBar.new
Run Code Online (Sandbox Code Playgroud)

|| =原子地将给定表达式的结果分配给变量,但前提是尚未设置变量。您最终可以得到两个FooBar.new实例,但是只有一个实例可以访问。Ruby on Rails在内部使用此技术来避免在某些地方使用互斥体。