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()); }