可能是重复内容:
Ruby是否有Java中'synchronized'关键字的等价物?
在Java中,我们可以通过在函数定义中使用“synchronized”关键字来使方法同步。
那么在Ruby中该怎么做呢?
可能是重复内容:
Ruby是否有Java中'synchronized'关键字的等价物?
在Java中,我们可以通过在函数定义中使用“synchronized”关键字来使方法同步。
那么在Ruby中该怎么做呢?
在 Ruby 中没有同步关键字。相反,可以将方法调用包装到 Mutex(即锁的花哨说法)中。
为该类创建新的共享 Mutex(每个人都必须使用相同的 Mutex(锁)来访问相同的变量):
NUM_THREADS = 4
class Foo
def initialize
@my_mutex = Mutex.new
@my_val = 0 # should be private
end
def synchronize(&block)
# to see what it does without the mutex in this example:
# 1) comment this line
@my_mutex.synchronize(&block)
# 2) uncomment this line
# yield
end
def current_value
synchronize do
@my_val
end
end
def modify
# the value should be 0 before and 0 after, if the Mutex is used correctly
synchronize do
@my_val += 1
sleep 0.25
@my_val -= 1
sleep 0.25
end
end
end
foo = Foo.new
threads = []
# spawn N threads, all trying to change the value
threads += (1..NUM_THREADS).map { |i|
Thread.new {
puts "thread [##{i}]: modifying"
foo.modify
}
}
# spawn checking thread
threads << Thread.new {
# print the value twice as fast as the other threads are changing it, so we are more likely to stumble upon wrong state
(NUM_THREADS * 2).times {
puts "thread [check]: checking..."
raise if foo.current_value != 0 # locking failed, crash
sleep 0.25
}
}
threads.map { |t| t.join } # wait for all threads
puts "even though it took a while longer, it didn't crash, everyone is happy, managers didn't fire me... it worked!"
synchronize
,它使用类定义的Mutex
。Mutex.new.synchronize
是无用的。因为你没有保留对新创建的Mutex的引用,所以没有其他线程可以尝试锁定它,因此它将永远不会从关键区域中排除任何线程(这正是互斥锁的全部目的)。 - Alex D@my_mutex.synchronize do
,答案还是一样的 - 0
。所以这并不是非常清晰的答案。主要是代码执行的顺序。 - skywinder