Bird
Raised Fist0
Rubyprogramming~20 mins

Thread safety concepts in Ruby - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Thread Safety Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
Output of thread increment without synchronization
What is the output of this Ruby code that increments a shared counter from multiple threads without any synchronization?
Ruby
counter = 0
threads = []
10.times do
  threads << Thread.new do
    1000.times { counter += 1 }
  end
end
threads.each(&:join)
puts counter
AA number greater than 10000
B10000
CRaises a runtime error
DA number less than 10000
Attempts:
2 left
💡 Hint
Think about what happens when multiple threads update the same variable without locks.
🧠 Conceptual
intermediate
1:30remaining
Understanding Mutex usage in Ruby
Why do we use a Mutex in Ruby when working with threads?
ATo allow multiple threads to access a resource simultaneously
BTo speed up thread execution by skipping locks
CTo prevent multiple threads from accessing a shared resource at the same time
DTo automatically create new threads
Attempts:
2 left
💡 Hint
Think about what happens if two threads try to change the same data at once.
🔧 Debug
advanced
2:30remaining
Identify the cause of inconsistent output in threaded code
This Ruby code uses threads to append to an array. Why might the final array length be less than expected?
Ruby
arr = []
threads = []
5.times do
  threads << Thread.new do
    100.times { arr << 1 }
  end
end
threads.each(&:join)
puts arr.length
ABecause Array#<< is not thread-safe and can cause lost updates
BBecause threads are not started properly
CBecause the array is frozen and cannot be modified
DBecause the join method is not waiting for threads
Attempts:
2 left
💡 Hint
Consider if appending to an array is safe when multiple threads do it at once.
📝 Syntax
advanced
2:00remaining
Identify the syntax error in thread synchronization code
Which option contains a syntax error in Ruby code that uses a Mutex to synchronize threads?
Ruby
mutex = Mutex.new
counter = 0
threads = []
10.times do
  threads << Thread.new do
    mutex.synchronize do
      counter += 1
    end
  end
end
threads.each(&:join)
puts counter
Amutex.synchronize counter += 1 end
Bmutex.synchronize do counter += 1 end
Cmutex.synchronize { counter += 1 }
D
mutex.synchronize do
  counter += 1
end
Attempts:
2 left
💡 Hint
Check the syntax of the block passed to synchronize.
🚀 Application
expert
3:00remaining
Determine the final value of a shared variable with thread-safe increments
Given this Ruby code using a Mutex to safely increment a shared counter from multiple threads, what is the final value of counter?
Ruby
counter = 0
mutex = Mutex.new
threads = []
20.times do
  threads << Thread.new do
    500.times do
      mutex.synchronize { counter += 1 }
    end
  end
end
threads.each(&:join)
puts counter
ARaises a deadlock error
B10000
CGreater than 10000 due to double increments
DLess than 10000 due to race conditions
Attempts:
2 left
💡 Hint
Mutex ensures increments happen one at a time without loss.

Practice

(1/5)
1. What is the main purpose of thread safety in Ruby programs?
easy
A. To make the program run slower
B. To prevent errors when multiple threads access shared data
C. To allow threads to run without any synchronization
D. To avoid using threads altogether

Solution

  1. Step 1: Understand thread safety concept

    Thread safety means making sure multiple threads do not cause errors when they access the same data.
  2. Step 2: Identify the main goal

    The main goal is to prevent errors and data corruption when threads run at the same time.
  3. Final Answer:

    To prevent errors when multiple threads access shared data -> Option B
  4. Quick Check:

    Thread safety = prevent errors [OK]
Hint: Thread safety means safe shared data access [OK]
Common Mistakes:
  • Thinking thread safety slows down programs
  • Believing threads never need synchronization
  • Confusing thread safety with avoiding threads
2. Which Ruby code snippet correctly uses a Mutex to protect a shared variable counter?
easy
A. mutex.synchronize { counter += 1 }
B. mutex.lock { counter += 1 }
C. mutex.unlock { counter += 1 }
D. mutex.wait { counter += 1 }

Solution

  1. Step 1: Recall Mutex usage in Ruby

    Mutex uses the synchronize method to safely run code blocks.
  2. Step 2: Check each option

    Only mutex.synchronize { ... } is the correct syntax to lock and unlock automatically.
  3. Final Answer:

    mutex.synchronize { counter += 1 } -> Option A
  4. Quick Check:

    Mutex uses synchronize method [OK]
Hint: Use synchronize to lock Mutex safely [OK]
Common Mistakes:
  • Using lock or unlock methods incorrectly
  • Trying to pass a block to lock or unlock
  • Confusing wait with Mutex methods
3. What will be the output of this Ruby code?
require 'thread'
mutex = Mutex.new
counter = 0
threads = 5.times.map do
  Thread.new do
    10.times do
      mutex.synchronize { counter += 1 }
    end
  end
end
threads.each(&:join)
puts counter
medium
A. 10
B. 0
C. 5
D. 50

Solution

  1. Step 1: Analyze thread and loop counts

    There are 5 threads, each incrementing counter 10 times, total increments = 5 * 10 = 50.
  2. Step 2: Understand Mutex protection

    Mutex ensures increments happen safely without lost updates, so counter will be exactly 50.
  3. Final Answer:

    50 -> Option D
  4. Quick Check:

    5 threads * 10 increments = 50 [OK]
Hint: Multiply threads by increments with Mutex [OK]
Common Mistakes:
  • Ignoring Mutex and expecting less than 50
  • Confusing thread count with increments
  • Assuming race conditions reduce count
4. Identify the problem in this Ruby code that uses threads:
counter = 0
threads = 3.times.map do
  Thread.new do
    100.times { counter += 1 }
  end
end
threads.each(&:join)
puts counter
medium
A. Thread.new syntax is incorrect
B. Threads are not joined, so program ends early
C. No Mutex used, so race condition may cause wrong counter value
D. Counter variable is not initialized

Solution

  1. Step 1: Check thread safety of counter increment

    Multiple threads increment counter without synchronization, causing race conditions.
  2. Step 2: Identify missing Mutex usage

    Without Mutex, increments can overlap and produce incorrect final value.
  3. Final Answer:

    No Mutex used, so race condition may cause wrong counter value -> Option C
  4. Quick Check:

    Missing Mutex causes race condition [OK]
Hint: Always use Mutex to protect shared variables [OK]
Common Mistakes:
  • Thinking threads are not joined (they are)
  • Assuming counter needs initialization (it is initialized)
  • Believing Thread.new syntax is wrong
5. You want to safely update a shared hash results from multiple threads in Ruby. Which approach correctly ensures thread safety?
hard
A. Use a Mutex and wrap all results[key] = value assignments inside mutex.synchronize
B. Use Thread.new without any synchronization because Ruby hashes are thread-safe
C. Create a new hash inside each thread and merge them later without synchronization
D. Use sleep to delay threads and avoid conflicts

Solution

  1. Step 1: Understand thread safety for shared hashes

    Ruby hashes are not thread-safe for writes; concurrent writes can cause errors or data loss.
  2. Step 2: Use Mutex to protect hash updates

    Wrapping assignments inside mutex.synchronize ensures only one thread writes at a time.
  3. Final Answer:

    Use a Mutex and wrap all results[key] = value assignments inside mutex.synchronize -> Option A
  4. Quick Check:

    Mutex protects shared hash writes [OK]
Hint: Protect shared hash writes with Mutex synchronize [OK]
Common Mistakes:
  • Assuming Ruby hashes are thread-safe for writes
  • Using sleep to avoid conflicts (not reliable)
  • Merging hashes without synchronization risks data loss
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