¿Por qué funciona de manera diferente el método #join en un objeto Thread cuando se llama con un iterador que con un bucle?
Aplicar #join en objetos de Thread dentro de un bucle los ejecuta de forma secuencial.
5.times do |x|
Thread.new {
t = rand(1..5) * 0.25
sleep(t)
puts "Hilo #{x}: #{t} segundos"
}.join
end
# Salida
# Hilo 0: 1.25 segundos
# Hilo 1: 1.25 segundos
# Hilo 2: 0.5 segundos
# Hilo 3: 0.75 segundos
# Hilo 4: 0.25 segundos
Por otro lado, aplicar #join a un arreglo de objetos de Thread con un iterador los ejecuta de forma concurrente. ¿Por qué?
threads = []
5.times do |x|
threads << Thread.new {
t = rand(1..5) * 0.25
sleep(t)
puts "Hilo #{x}: #{t} segundos"
}
end
threads.each(&:join)
# Salida
# Hilo 1: 0.25 segundos
# Hilo 3: 0.5 segundos
# Hilo 0: 1.0 segundos
# Hilo 4: 1.0 segundos
# Hilo 2: 1.25 segundos
davy.ai
Cuando #join se aplica en objetos de hilo dentro de un bucle, se ejecutan de manera secuencial porque cada hilo se inicia y se une antes de que comience el siguiente. En el código dado, el bucle crea un nuevo hilo, espera a que se complete usando join y luego pasa a la siguiente iteración para crear el siguiente hilo.
Por otro lado, cuando #join se aplica a un arreglo de objetos de hilo con un iterador, se ejecutan de manera concurrente porque se crea cada hilo y se agrega al arreglo de hilos, y luego todos los hilos son unidos usando el iterador #each. Esto permite que cada hilo se ejecute de manera independiente y simultánea, lo que resulta en una salida aleatoria y no secuencial.
En resumen, aplicar #join en objetos de hilo dentro de un bucle los ejecuta de manera secuencial, mientras que aplicar #join a un arreglo de objetos de hilo con un iterador los ejecuta de manera concurrente.