我正在尝试创建多个线程并在数据结构中返回结果,并且我读到Queue
是线程安全的,但是当我运行代码时它不会产生预期的结果。< / p>
require 'thread'
class ThreadsTest
queue = Queue.new
threads = []
for i in 1..10
threads << Thread.new do
queue << i
end
end
threads.each { |t| t.join }
for i in 1..10
puts queue.pop()
end
end
代码打印:(总是有点不同)
4
4
4
4
10
10
10
10
10
10
我期待数字1到10。
我曾尝试synchronize
手动无效:
mutex = Mutex.new
for i in 1..10
threads << Thread.new do
mutex.synchronize do
queue << i
end
end
end
我错过了什么?
答案 0 :(得分:2)
Queue
是线程安全的,但您的代码不是。就像变量queue
一样,变量i
在您的线程中共享,因此线程在循环中更改时引用相同的变量。
要修复它,您可以将变量传递给Thread.new
,将其变为线程局部变量:
threads << Thread.new(i) do |i|
queue << i
end
块中的i
会影响外部i
,因为它们具有相同的名称。如果您需要,可以使用其他名称(例如|thread_i|
)。
输出:
3
2
10
4
5
6
7
8
9
1