Thread-local values let each thread keep its own context while sharing the same code path.

Thread Local Context

thread_local_context.rb
prefix = 
labels = []
lock = Mutex.new

workers = 2.times.map do |index|
  Thread.new do
    Thread.current[:label] = "#{prefix}-#{index + 1}"
    label = Thread.current[:label]

    lock.synchronize do
      labels << label
    end
  end
end

workers.each(&:join)

puts "prefix=#{prefix}"
puts "labels=#{labels.sort.join(",")}"
puts "count=#{labels.length}"
prefix = 
labels = []
lock = Mutex.new

workers = 2.times.map do |index|
  Thread.new do
    Thread.current[:label] = "#{prefix}-#{index + 1}"
    label = Thread.current[:label]

    lock.synchronize do
      labels << label
    end
  end
end

workers.each(&:join)

puts "prefix=#{prefix}"
puts "labels=#{labels.sort.join(",")}"
puts "count=#{labels.length}"
prefix = 
labels = []
lock = Mutex.new

workers = 2.times.map do |index|
  Thread.new do
    Thread.current[:label] = "#{prefix}-#{index + 1}"
    label = Thread.current[:label]

    lock.synchronize do
      labels << label
    end
  end
end

workers.each(&:join)

puts "prefix=#{prefix}"
puts "labels=#{labels.sort.join(",")}"
puts "count=#{labels.length}"
thread locals Use `Thread.current[...]` when each thread needs a private value that should not overwrite another thread's value.