// Copyright 2026 Amber Hu
use std::thread;
use std::sync::Mutex;
fn main() {
let mut handlers = Vec::new();
for name in 'a'..'e' {
println!("Spawning thread {name}");
// Anonymous function syntax
let handler = thread::spawn(move || {
for i in 0..5 {
println!("Thread {name} Iteration {i}");
}
});
handlers.push(handler);
}
for handler in handlers {
handler.join().unwrap();
}
// Now let's synchronize mutable data across threads using Mutex
let counter = Mutex::new(0);
println!("Original data value: {:?}", counter.lock().unwrap());
incr_scoped(4, 100, &counter);
println!("Final data value: {:?}", counter.lock().unwrap());
}
fn incr_scoped(threads: u32, iters : u32, data : &Mutex<i32>) {
// thread::scope does the joining for us, and lets us borrow `data` by ref
thread::scope(|s| {
for _ in 0..4 {
s.spawn(|| {
for _ in 0..100 {
let mut mutex_guard = data.lock().unwrap();
*mutex_guard += 1;
// Don't need to unlock, because it automatically
// unlocks after mutex_guard goes out of scope!
}
});
}
// All threads are automatically joined here
});
}