Showed an example, that raceconditions are still possible even with mutex

main
3008505 2026-06-13 13:00:32 +00:00
parent 9e36ee2d01
commit b67f32704e
1 changed files with 58 additions and 0 deletions

View File

@ -0,0 +1,58 @@
use std::sync::{Arc, Mutex};
use std::thread;
use std::time::Duration;
fn main() {
// A shared bank account starting with $100
let account_balance = Arc::new(Mutex::new(100));
// Thread A: Attempts to withdraw $80
let balance_clone1 = Arc::clone(&account_balance);
let handle1 = thread::spawn(move || {
// 1. CHECK: Lock the account just to check the balance
let current_balance = *balance_clone1.lock().unwrap();
if current_balance >= 80 {
println!("Thread A: Balance is ${}. Approval granted!", current_balance);
// Simulate a tiny delay (e.g., network latency or CPU context switch)
// This gives Thread B time to sneak in and check the balance
thread::sleep(Duration::from_millis(5));
// 2. ACT: Lock again to deduct the money
let mut balance_guard = balance_clone1.lock().unwrap();
*balance_guard -= 80;
println!("Thread A: Successfully withdrew $80.");
} else {
println!("Thread A: Declined. Insufficient funds.");
}
});
// Thread B: Simultaneously attempts to withdraw $80
let balance_clone2 = Arc::clone(&account_balance);
let handle2 = thread::spawn(move || {
// 1. CHECK: Lock the account just to check the balance
let current_balance = *balance_clone2.lock().unwrap();
if current_balance >= 80 {
println!("Thread B: Balance is ${}. Approval granted!", current_balance);
// Simulate a tiny delay (e.g., network latency or CPU context switch)
// This gives Thread B time to sneak in and check the balance
thread::sleep(Duration::from_millis(5));
// 2. ACT: Lock again to deduct the money
let mut balance_guard = balance_clone2.lock().unwrap();
*balance_guard -= 80;
println!("Thread B: Successfully withdrew $80.");
} else {
println!("Thread B: Declined. Insufficient funds.");
}
});
handle1.join().unwrap();
handle2.join().unwrap();
// Final result
println!("Final Bank Balance: ${}", *account_balance.lock().unwrap());
}