我有一个班级和属性
class Person
attr_accessor :name
def say_hello
puts "person name #{self.name} "
end
end
现在我想执行方法say_hello但是使用这个帖子
queue_thread= []
1..100.times do |number|
person= Person.new
person.name= number.to_s
thread_to_run=Thread.new {person.say_hello}
queue_thread << thread_to_run
end
queue_thread.map {|thread_current| thread_current.join}
你有什么想法吗?我看了,而且这个问题比线程不是通过对象实例识别vars。
答案正确应该在控制台中
"person name 1"
"person name 2"
"person name ..."
"person name etc"
答案 0 :(得分:0)
此代码的问题在于它在调用join
之前触发多个线程 - 此时,由于线程的异步性质,某些线程可能以不正确的顺序被调用。
一旦调用线程,一个选项就是join
。这实际上会暂停迭代直到线程完成,因此您知道它们将保持有序:
100.times do |number|
person= Person.new
person.name= number.to_s
Thread.new {person.say_hello}.join
end
请注意,此处使用线程确实没有意义,但它至少会显示join
可以正常工作。
另一个选项(也不必要地使用线程)通过将它存储为lambda来延迟线程调用。这基本上是相同的,但允许您将其拆分为两个迭代:
queue_threads= []
1..100.times do |number|
person= Person.new
person.name= number.to_s
thread_lambda = -> { Thread.new {person.say_hello} }
queue_threads.push(thread_lambda)
end
queue_threads.map {|thread_lambda| thread_lambda.call.join}
另请注意,1..100.times
并未按照您的想法行事。这与说100.times
是一回事,因此,例如,如果你说99..100.times
,99将被忽略,它将是100次迭代而不仅仅是1.如果你想迭代一个范围,你可以使用类似99..100.each do |i|
的东西。