Ruby Threads

Running multiple tasks simultaneously in Ruby

🧡 What are Ruby Threads?

Threads allow your Ruby program to run multiple tasks at the same time. They help improve performance by executing code concurrently, making your applications faster and more responsive.


# Simple thread example
thread = Thread.new do
  puts "Hello from thread!"
end
thread.join
                                    

Output:

Hello from thread!

Key Thread Concepts

πŸš€

Creating Threads

Start new threads with Thread.new

t = Thread.new { puts "Running!" }
⏸️

Joining Threads

Wait for threads to complete

thread.join
πŸ’€

Thread Sleep

Pause thread execution

sleep(2) # Sleep for 2 seconds
πŸ“Š

Thread Status

Check if thread is alive

thread.alive?

πŸ”Ή Creating Multiple Threads

You can create multiple threads to perform different tasks simultaneously. Each thread runs independently and can execute different code blocks at the same time.

# Create multiple threads
thread1 = Thread.new do
  5.times { |i| puts "Thread 1: #{i}" }
end

thread2 = Thread.new do
  5.times { |i| puts "Thread 2: #{i}" }
end

# Wait for both threads to finish
thread1.join
thread2.join
puts "All threads completed!"

Output:

Thread 1: 0

Thread 2: 0

Thread 1: 1

Thread 2: 1

...

All threads completed!

πŸ”Ή Thread with Parameters

Pass arguments to threads to make them more flexible. You can send data to threads when creating them, allowing each thread to work with different values.

# Pass parameters to thread
thread = Thread.new("Ruby", 2024) do |language, year|
  puts "Learning #{language} in #{year}"
end

thread.join

Output:

Learning Ruby in 2024

πŸ”Ή Thread Variables

Each thread can have its own local variables that don't interfere with other threads. Thread-local variables are useful for storing data specific to each thread's execution.

# Thread-local variables
thread = Thread.new do
  Thread.current[:name] = "Worker Thread"
  puts Thread.current[:name]
end

thread.join

# Main thread variable
Thread.current[:name] = "Main Thread"
puts Thread.current[:name]

Output:

Worker Thread

Main Thread

πŸ”Ή Thread Synchronization

When multiple threads access shared data, use Mutex to prevent conflicts. Mutex ensures only one thread can access the protected code at a time, preventing data corruption.

# Using Mutex for thread safety
mutex = Mutex.new
counter = 0

threads = 5.times.map do
  Thread.new do
    mutex.synchronize do
      temp = counter
      temp += 1
      counter = temp
    end
  end
end

threads.each(&:join)
puts "Counter: #{counter}"

Output:

Counter: 5

πŸ”Ή Practical Thread Example

Here's a real-world example of downloading multiple files concurrently using threads. This demonstrates how threads can speed up I/O operations significantly.

# Simulate downloading files
files = ["file1.txt", "file2.txt", "file3.txt"]

threads = files.map do |file|
  Thread.new(file) do |f|
    puts "Downloading #{f}..."
    sleep(1) # Simulate download time
    puts "#{f} downloaded!"
  end
end

threads.each(&:join)
puts "All downloads complete!"

Output:

Downloading file1.txt...

Downloading file2.txt...

Downloading file3.txt...

file1.txt downloaded!

file2.txt downloaded!

file3.txt downloaded!

All downloads complete!

🧠 Test Your Knowledge

What method is used to wait for a thread to finish?