2017-08-10 63 views
1

我想创建多个线程并返回数据结构的结果,我读了Queue是线程安全的,但是当我运行代码时,它不会产生预期的结果。不是ruby队列线程安全为什么队列不同步?

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 

我是通过10.

期望数字1我试图synchronize它手动无济于事:

mutex = Mutex.new 
    for i in 1..10 
    threads << Thread.new do 
     mutex.synchronize do 
     queue << i 
     end 
    end 
    end 

我错过了什么?

+0

顺便说一句,这是奇怪的把这样的代码对入'class'块。你应该用一种方法来包装它。 – Stefan

回答

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