【发布时间】:2017-02-11 18:43:46
【问题描述】:
有人可以举一个具体的例子来证明非线程安全吗? (如果可能,与我的功能版本类似)
我需要一个示例类来演示非线程安全操作,以便我可以断言失败,然后强制执行互斥锁,以便我可以测试我的代码是否是线程安全的。
我尝试了以下但没有成功,因为线程似乎没有并行运行。假设 ruby += 运算符不是线程安全的,这个测试总是在它不应该通过的时候通过:
class TestLock
attr_reader :sequence
def initialize
@sequence = 0
end
def increment
@sequence += 1
end
end
#RSpec test
it 'does not allow parallel calls to increment' do
test_lock = TestLock.new
threads = []
list1 = []
list2 = []
start_time = Time.now + 2
threads << Thread.new do
loop do
if Time.now > start_time
5000.times { list1 << test_lock.increment }
break
end
end
end
threads << Thread.new do
loop do
if Time.now > start_time
5000.times { list2 << test_lock.increment }
break
end
end
end
threads.each(&:join) # wait for all threads to finish
expect(list1 & list2).to eq([])
end
【问题讨论】:
-
线程是不确定的。这就是让他们如此丑陋的原因。你不能让它们确定性地失败。即使您的锁定不正确,它们有时也会正常工作。你用你的代码完美地证明了这一点,它在 YARV 上工作,在 JRuby 和 Rubinius 上失败。
标签: ruby-on-rails ruby multithreading