在线程上调用join
将阻止父线程,而要连接的线程尚未完成。为了检查这一点,我创建了这段代码:
threads = []
3.times do |i|
threads << Thread.new do
3.times do |j|
puts "Thread #{i} says #{j} (#{Thread.current})"
sleep 0.1
end
end
end
#threads.map(&:join)
threads[0].join
puts "After first join"
threads[1].join
puts "After second join"
threads[2].join
puts "Last line of main thread"
运行此类代码会产生以下输出:
Thread 0 says 0 (#<Thread:0x007fdceb0b8568>)
Thread 2 says 0 (#<Thread:0x007fdce982bb08>)
Thread 1 says 0 (#<Thread:0x007fdceb0b8450>)
Thread 0 says 1 (#<Thread:0x007fdceb0b8568>)
Thread 1 says 1 (#<Thread:0x007fdceb0b8450>)
Thread 2 says 1 (#<Thread:0x007fdce982bb08>)
Thread 1 says 2 (#<Thread:0x007fdceb0b8450>)
Thread 2 says 2 (#<Thread:0x007fdce982bb08>)
Thread 0 says 2 (#<Thread:0x007fdceb0b8568>)
After first join
After second join
Last line of main thread
为什么ruby在线程&#39;之后打印After first join
。尽管指令threads[1].join
是在此打印指令之后执行的?
答案 0 :(得分:3)
因为puts "Thread #{i} says #{j} (#{Thread.current})"
threads[1]
部分(或可能全部)puts "After first join"
在threads[1].join
之前完成。在puts "After first join"
之后puts "Thread #{i} says #{j} (#{Thread.current})"
执行的事实不会影响结果。
你似乎有两点逻辑缺陷。它们应该按如下方式纠正:
threads[1]
的{{1}}在主线程的puts "After first join"
之前完成,那么整个threads[1]
是否在puts "After first join"
开始之前完成是无关紧要的。< / LI>
threads[1]
有机会在主线程执行puts "After first join"
之前完成。 threads[1].join
仅显示效果。可能发生的事情(实际发生的事情)是,因为在任何threads[0].join
方法调用之前你有puts
,所以主线程一直在睡眠,直到threads[0]
完成。由于threads[1]
和threads[2]
在threads[0]
之后立即启动,因此三个子线程大致几乎同时完成。换句话说,如果你等待threads[0]
完成的时间足够长,那么其他两个线程很可能也会完成。