📖 Scenario: Imagine you are building a simple bank system where multiple people can deposit money into the same account at the same time. To keep the account balance correct, you need to make sure that the updates to the balance are done safely when many threads work together.
🎯 Goal: You will create a Ruby program that shows how to safely update a shared bank account balance using thread safety concepts.
📋 What You'll Learn
Create a shared bank account balance variable
Create a mutex lock to control access to the balance
Use multiple threads to deposit money safely
Print the final balance after all deposits
💡 Why This Matters
🌍 Real World
Thread safety is important in real-world programs where many tasks run at the same time and share data, like banking apps or online stores.
💼 Career
Understanding thread safety helps you write reliable and bug-free code in jobs that involve concurrent programming or server-side development.
Progress0 / 4 steps
1
Create the shared bank account balance
Create a variable called balance and set it to 0 to represent the starting bank account balance.
Ruby
Hint
Use a simple variable assignment like balance = 0.
2
Create a mutex lock for thread safety
Create a variable called mutex and set it to a new Mutex object to control access to the shared balance.
Ruby
Hint
Use Mutex.new to create a new lock.
3
Use threads to deposit money safely
Create 5 threads that each add 100 to balance safely using mutex.synchronize to lock the update. Use a variable called threads to store the thread objects.
Ruby
Hint
Use 5.times do to create threads, and inside each thread use mutex.synchronize to safely update balance.
4
Print the final balance
Write a puts statement to print the final value of balance after all threads have finished.
Ruby
Hint
Use puts balance to show the final amount.
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
Step 1: Understand thread safety concept
Thread safety means making sure multiple threads do not cause errors when they access the same data.
Step 2: Identify the main goal
The main goal is to prevent errors and data corruption when threads run at the same time.
Final Answer:
To prevent errors when multiple threads access shared data -> Option B
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
Step 1: Recall Mutex usage in Ruby
Mutex uses the synchronize method to safely run code blocks.
Step 2: Check each option
Only mutex.synchronize { ... } is the correct syntax to lock and unlock automatically.
Final Answer:
mutex.synchronize { counter += 1 } -> Option A
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
Step 1: Analyze thread and loop counts
There are 5 threads, each incrementing counter 10 times, total increments = 5 * 10 = 50.
Step 2: Understand Mutex protection
Mutex ensures increments happen safely without lost updates, so counter will be exactly 50.
Final Answer:
50 -> Option D
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
Step 1: Check thread safety of counter increment
Multiple threads increment counter without synchronization, causing race conditions.
Step 2: Identify missing Mutex usage
Without Mutex, increments can overlap and produce incorrect final value.
Final Answer:
No Mutex used, so race condition may cause wrong counter value -> Option C
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
Step 1: Understand thread safety for shared hashes
Ruby hashes are not thread-safe for writes; concurrent writes can cause errors or data loss.
Step 2: Use Mutex to protect hash updates
Wrapping assignments inside mutex.synchronize ensures only one thread writes at a time.
Final Answer:
Use a Mutex and wrap all results[key] = value assignments inside mutex.synchronize -> Option A
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 unknownstrongwhile earning +1 Grip toward your certificate.