58 lines
2.2 KiB
Rust
58 lines
2.2 KiB
Rust
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());
|
|
} |