Ruby 类变量和初始化时间
如果我像这样创建一个类变量:Ruby 类变量和初始化时间,ruby,thread-safety,jruby,Ruby,Thread Safety,Jruby,如果我像这样创建一个类变量: class Song @@plays = 0 class << self def plays=( plays ) @@plays += plays end def plays @@plays end end end 是否可以让两个线程同时初始化@播放到0?类变量是在执行的哪个阶段创建的?@@plays=0是在Ruby计算类定义时设置的。这应该只发生一次,并且在启动线程之前 另
class Song
@@plays = 0
class << self
def plays=( plays )
@@plays += plays
end
def plays
@@plays
end
end
end
是否可以让两个线程同时初始化@播放到0?类变量是在执行的哪个阶段创建的?
@@plays=0
是在Ruby计算类定义时设置的。这应该只发生一次,并且在启动线程之前
另一方面,赋值方法plays=
可以同时执行。因此,您应该将其包装在通话中,例如:
require 'thread'
require 'song' # <- @@plays is set to 0 here
Song.plays #=> 0
semaphore = Mutex.new
t1 = Thread.new { semaphore.synchronize { Song.plays = 1 } }
t2 = Thread.new { semaphore.synchronize { Song.plays = 5 } }
t3 = Thread.new { semaphore.synchronize { Song.plays = 3 } }
[t1, t2, t3].each(&:join)
Song.plays #=> 9
你的代码对我不起作用。没有
Song#plays=
,而是将此方法创建为Song
的singleton类上的类方法。我补充说,已修复。习惯性新增。不,仍然不起作用Song.singleton_class.plays=
可以工作,但这可能不是您想要的。我修复了它,但它没有按预期工作。您现在既有一个实例方法,也有一个类方法,即Song.singleton_class.plays=
和Song.singleton_class#plays=
。后者相当于Song.plays=
,但它不调用您的方法。提示:删除类我是否应该在类变量中创建互斥,以确保它不是由2个线程同时创建的?同一个问题的措辞不同,您如何使Song类线程安全?@KieranAndrews是的,创建互斥锁就像@@plays
,即在启动线程之前。我怀疑这能否回答问题。它无论如何都不能确保两个线程以开头。@@plays==0
。它可以通过传递给线程的可选参数进行设置。new
,但是仍然没有达到他想要达到的目的。@DavidUnric是的,几个线程可以从(仍然)设置为0
开始。但是一次只能有一个线程增加类变量。
require 'thread'
require 'song' # <- @@plays is set to 0 here
Song.plays #=> 0
semaphore = Mutex.new
t1 = Thread.new { semaphore.synchronize { Song.plays = 1 } }
t2 = Thread.new { semaphore.synchronize { Song.plays = 5 } }
t3 = Thread.new { semaphore.synchronize { Song.plays = 3 } }
[t1, t2, t3].each(&:join)
Song.plays #=> 9
class Song
@@plays = 0
@@semaphore = Mutex.new
def self.plays=(plays)
@@semaphore.synchronize { @@plays += plays }
end
# ...
end