From: Robert Klemme Date: 2009-11-10T07:01:38+09:00 Subject: Re: Understanding Threads... On 11/09/2009 10:24 PM, Judson Lester wrote: > I completely agree with Jason's diagnosis. I'd like to make two > observations, though. > > First, you can avoid the mutex entirely by using thread-local variables: > > threads << Thread.new { Thread.current[:result] = method1(string) } > > results = threads.inject({}) do |results, thread| > thread.join > results.merge(thread[:result]) > end Even better: we have Thread.value. If you join only from a single thread there is no additional synchronization needed: irb(main):001:0> t = (1..5).map {|i| Thread.new(i) {|x| "value #{x}"} } => [#, #, #, #, #] irb(main):002:0> t.map {|th| th.value} => ["value 1", "value 2", "value 3", "value 4", "value 5"] > Second, and (possibly) more controversially, just because you can eval > doesn't mean you should. To my eye, this looks nicer: > > threads = [ > Thread.new { Thread.current[:result] = method1(string) }, > Thread.new { Thread.current[:result] = method2(string) }, > Thread.new { Thread.current[:result] = method3(string) }, > Thread.new { Thread.current[:result] = method4(string) } > ] > > And exception handling, etc, will be ever so much clearer. You can as well do def method(string) threads = %w{ methodname1 methodname2 methodname3 methodname4 }.map do |method| Thread.new(method) do |m| send(m, string) # each method call makes an HTTP request end.map {|th| th.value} end and be done. Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/