这不是固有线程安全的,尽管这将取决于正是正在做和什么。而且,实现 - 例如具有“绿色线程”的Ruby 1.8 MRI与Ruby 2 MRI与JRuby等 - 将在竞争条件(如果有的话)将如何实现方面发挥作用。
请记住,竞争条件通常是由共享数据引起的。这些变量并不重要(并且一个线程不会使用另一个线程局部变量,除非递归方法将重用变量),但变量命名的对象是重要。 (注:proxy
是局部变量但proxy.instance
是不局部变量!)
竞争条件假设共享数据/对象:
proxy_A = popFromGlobalArray()
proxy_B = popFromGlobalArray()
# assume same object was returned so that proxy_A.equal? proxy_B is true
proxy_A.identifier = Time.now.to_i
proxy_A.active = 1
proxy_B.identifier = Time.now.to_i # such that it is different
proxy_B.active = 1
这是不是很兴奋这里因为结果在这一点是一样的,但想象一下如果返回的对象(其中proxy_A和proxy_B 都 refe r)已被用于之间的标识符变量的分配(和线程可见性传播) - 破码。
也就是说,假设上述扩展:
h = {}
# assume same object was returned so that proxy_A.equal? proxy_B is true
proxy_A.identifier = Time.now.to_i
h[proxy_A.identifier] = proxy_A # i.e. used after return
proxy_B.identifier = Time.now.to_i # such that it is different
h[proxy_B.identifier] = proxy_B # i.e. used after return
# now there may be an orphaned key/value.
当然,如果popFromGlobalArray
保证返回不同对象则以上不适用,但还有另外一个问题 - 比赛情况取决于时间精度:
proxy_A = popFromGlobalArray()
proxy_B = popFromGlobalArray()
# assume Time.now.to_i returns x for both threads
proxy_A.identifier = x
proxy_B.identifier = x
# and a lost proxy ..
h = {}
h[proxy_A.identifier] = proxy_A
h[proxy_B.identifier] = proxy_B
道德故事:不要依靠运气。我简化了上述内容,以显示线程间数据可见性可能发生的竞争条件。但是,线程之间的数据可见性(即缺少内存防护)使得这个问题远比最初看起来更糟糕。
有没有**共享数据**?也就是说,两个线程可以同时引用*相同的*代理对象吗? – 2013-03-29 22:55:56