diff --git a/G-concurrency/racecondition.rs b/G-concurrency/racecondition.rs new file mode 100644 index 0000000..44b877f --- /dev/null +++ b/G-concurrency/racecondition.rs @@ -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()); +} \ No newline at end of file