Bird
Raised Fist0
Rubyprogramming~20 mins

Thread synchronization with Mutex in Ruby - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Mutex Mastery
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
What is the output of this Ruby code using Mutex?

Consider the following Ruby code that uses a Mutex to synchronize threads incrementing a shared counter.

require 'thread'
counter = 0
mutex = Mutex.new
threads = []

10.times do
  threads << Thread.new do
    100.times do
      mutex.synchronize do
        counter += 1
      end
    end
  end
end

threads.each(&:join)
puts counter

What will be printed?

Ruby
require 'thread'
counter = 0
mutex = Mutex.new
threads = []

10.times do
  threads << Thread.new do
    100.times do
      mutex.synchronize do
        counter += 1
      end
    end
  end
end

threads.each(&:join)
puts counter
A0
BA number less than 1000 due to race conditions
CAn error because counter is not thread-safe
D1000
Attempts:
2 left
💡 Hint

Think about what the Mutex does to the shared variable.

❓ Predict Output
intermediate
2:00remaining
What happens if Mutex is removed from this Ruby code?

Look at this Ruby code where multiple threads increment a shared variable without a Mutex:

counter = 0
threads = []

10.times do
  threads << Thread.new do
    100.times do
      counter += 1
    end
  end
end

threads.each(&:join)
puts counter

What is the most likely output?

Ruby
counter = 0
threads = []

10.times do
  threads << Thread.new do
    100.times do
      counter += 1
    end
  end
end

threads.each(&:join)
puts counter
AA number less than 1000 due to race conditions
B1000
CAn error because counter is not thread-safe
D0
Attempts:
2 left
💡 Hint

Think about what happens when multiple threads change the same variable without protection.

🔧 Debug
advanced
2:00remaining
Identify the error in this Ruby Mutex usage

Find the error in this Ruby code snippet that tries to use a Mutex to protect a shared resource:

mutex = Mutex.new
counter = 0

Thread.new do
  mutex.lock
  counter += 1
end

mutex.unlock
puts counter
Ruby
mutex = Mutex.new
counter = 0

Thread.new do
  mutex.lock
  counter += 1
end

mutex.unlock
puts counter
Acounter is not initialized before use
BMissing mutex.synchronize block causes race condition
CCalling mutex.unlock outside the thread causes a ThreadError
DThread never starts because of missing join
Attempts:
2 left
💡 Hint

Think about which thread owns the lock when unlocking.

📝 Syntax
advanced
2:00remaining
Which Ruby code correctly uses Mutex to protect a shared array?

Choose the Ruby code snippet that correctly uses a Mutex to safely append to a shared array from multiple threads.

A
mutex = Mutex.new
arr = []
threads = []
10.times do
  threads &lt;&lt; Thread.new do
    mutex.synchronize { arr &lt;&lt; 1 }
  end
end
threads.each(&amp;:join)
puts arr.size
B
mutex = Mutex.new
arr = []
threads = []
10.times do
  threads &lt;&lt; Thread.new do
    mutex.synchronize do
      arr.push(1)
    end
  end
end
threads.each(&amp;:join)
puts arr.size
C
mutex = Mutex.new
arr = []
threads = []
10.times do
  threads &lt;&lt; Thread.new do
    mutex.lock
    arr &lt;&lt; 1
  end
  mutex.unlock
end
threads.each(&amp;:join)
puts arr.size
D
mutex = Mutex.new
arr = []
threads = []
10.times do
  threads &lt;&lt; Thread.new do
    arr &lt;&lt; 1
  end
end
threads.each(&amp;:join)
puts arr.size
Attempts:
2 left
💡 Hint

Look for proper use of synchronize and thread joining.

🚀 Application
expert
3:00remaining
How many items will the shared hash contain after this Ruby threaded code?

Consider this Ruby code that uses a Mutex to safely add keys to a shared hash from multiple threads:

require 'thread'
shared_hash = {}
mutex = Mutex.new
threads = []

5.times do |i|
  threads << Thread.new do
    10.times do |j|
      mutex.synchronize do
        shared_hash["key_#{i}_#{j}"] = i * j
      end
    end
  end
end

threads.each(&:join)
puts shared_hash.size

What will be printed?

Ruby
require 'thread'
shared_hash = {}
mutex = Mutex.new
threads = []

5.times do |i|
  threads << Thread.new do
    10.times do |j|
      mutex.synchronize do
        shared_hash["key_#{i}_#{j}"] = i * j
      end
    end
  end
end

threads.each(&:join)
puts shared_hash.size
A5
B50
C10
D0
Attempts:
2 left
💡 Hint

Count how many unique keys are added by all threads combined.

Practice

(1/5)
1. What is the main purpose of using a Mutex in Ruby threads?
easy
A. To create new threads automatically
B. To prevent multiple threads from accessing shared data at the same time
C. To speed up thread execution by running them in parallel
D. To stop threads from running

Solution

  1. Step 1: Understand what shared data means in threads

    Shared data is information that multiple threads can access or change.
  2. Step 2: Identify the role of Mutex

    Mutex ensures only one thread changes shared data at a time to avoid errors.
  3. Final Answer:

    To prevent multiple threads from accessing shared data at the same time -> Option B
  4. Quick Check:

    Mutex protects shared data = prevent simultaneous access [OK]
Hint: Mutex locks shared data to avoid conflicts between threads [OK]
Common Mistakes:
  • Thinking Mutex speeds up threads
  • Believing Mutex creates threads
  • Assuming Mutex stops threads completely
2. Which of the following is the correct way to use a Mutex to protect a critical section in Ruby?
easy
A. mutex.synchronize { critical_code }
B. mutex.lock; critical_code
C. mutex.run(critical_code)
D. mutex.start { critical_code }

Solution

  1. Step 1: Recall Mutex usage in Ruby

    Ruby's Mutex class provides a synchronize method to wrap critical code safely.
  2. Step 2: Compare options

    Only mutex.synchronize { critical_code } is the correct and safe syntax.
  3. Final Answer:

    mutex.synchronize { critical_code } -> Option A
  4. Quick Check:

    Use synchronize method to protect code [OK]
Hint: Use mutex.synchronize { } to wrap critical code [OK]
Common Mistakes:
  • Forgetting to unlock mutex after lock
  • Using non-existent methods like run or start
  • Not wrapping critical code in a block
3. What will be the output of this Ruby code?
require 'thread'
mutex = Mutex.new
counter = 0
threads = 3.times.map do
  Thread.new do
    2.times do
      mutex.synchronize { counter += 1 }
    end
  end
end
threads.each(&:join)
puts counter
medium
A. 2
B. 3
C. 6
D. 0

Solution

  1. Step 1: Count total increments

    There are 3 threads, each increments counter 2 times, total 3*2=6 increments.
  2. Step 2: Understand mutex effect

    Mutex ensures increments happen safely without losing counts, so final counter is 6.
  3. Final Answer:

    6 -> Option C
  4. Quick Check:

    3 threads * 2 increments each = 6 [OK]
Hint: Multiply threads by increments inside synchronize block [OK]
Common Mistakes:
  • Ignoring mutex and expecting wrong count
  • Counting only one thread's increments
  • Confusing thread join effect
4. Identify the problem in this Ruby code using Mutex and how to fix it:
require 'thread'
mutex = Mutex.new
counter = 0
threads = 2.times.map do
  Thread.new do
    mutex.lock
    counter += 1
  end
end
threads.each(&:join)
puts counter
medium
A. Threads are not joined properly; fix by joining inside the thread block
B. Mutex is not needed here; remove mutex.lock
C. counter should be initialized inside the thread
D. Missing mutex.unlock causes deadlock; fix by adding mutex.unlock after increment

Solution

  1. Step 1: Check mutex usage

    Mutex is locked but never unlocked, causing threads to wait forever (deadlock).
  2. Step 2: Fix by unlocking mutex

    After increment, call mutex.unlock or better use mutex.synchronize to auto-handle locking/unlocking.
  3. Final Answer:

    Missing mutex.unlock causes deadlock; fix by adding mutex.unlock after increment -> Option D
  4. Quick Check:

    Always unlock mutex after lock to avoid deadlock [OK]
Hint: Always unlock mutex or use synchronize block [OK]
Common Mistakes:
  • Forgetting to unlock mutex
  • Removing mutex when needed
  • Initializing shared data inside threads incorrectly
5. You want to safely update a shared hash from multiple threads in Ruby. Which approach correctly uses Mutex to avoid race conditions?
shared_hash = {}
mutex = Mutex.new
threads = 5.times.map do |i|
  Thread.new do
    10.times do |j|
      # What goes here?
    end
  end
end
threads.each(&:join)
puts shared_hash.size
hard
A. mutex.synchronize { shared_hash[i * 10 + j] = "value" }
B. shared_hash[i * 10 + j] = "value"
C. mutex.lock; shared_hash[i * 10 + j] = "value";
D. Thread.pass; shared_hash[i * 10 + j] = "value"

Solution

  1. Step 1: Understand thread safety for shared hash

    Multiple threads writing to shared_hash need protection to avoid data corruption.
  2. Step 2: Use mutex.synchronize for safe updates

    mutex.synchronize { shared_hash[i * 10 + j] = "value" } wraps the update inside mutex.synchronize, ensuring only one thread writes at a time.
  3. Final Answer:

    mutex.synchronize { shared_hash[i * 10 + j] = "value" } -> Option A
  4. Quick Check:

    Use synchronize block to protect shared hash updates [OK]
Hint: Wrap shared data updates inside mutex.synchronize { } [OK]
Common Mistakes:
  • Updating shared hash without mutex
  • Locking mutex without unlocking
  • Using Thread.pass instead of mutex
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard