如果我像这样创建一个类变量:
class Song
@@plays = 0
class << self
def plays=( plays )
@@plays += plays
end
def plays
@@plays
end
end
end
我有多个线程访问此类方法并在jruby中设置它:
t1 = Thread.new {st1 = Song.plays = 1}
t2 = Thread.new {st2 = Song.plays = 5}
t3 = Thread.new {st3 = Song.plays = 3}
是否可以让2个线程初始化@@同时播放到0?在执行的哪个阶段创建了类变量?
答案 0 :(得分:2)
@@plays = 0
。这应该只发生一次,然后才开始你的线程。
另一方面,分配方法plays=
可以同时执行。因此,您应将其包裹在synchronize
电话中,例如:
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
线程安全:
class Song
@@plays = 0
@@semaphore = Mutex.new
def self.plays=(plays)
@@semaphore.synchronize { @@plays += plays }
end
# ...
end