use std::fmt::Debug; use std::sync::Arc; use std::thread; use std::time; use init_once::InitOnce; struct AnnounceDrop { value: T, } fn main() { let init_once = Arc::new(InitOnce::new()); let threads: Vec<_> = (0..10) .map(|i| { let init_once = Arc::clone(&init_once); thread::spawn(move || { let worker_sleep_dur = time::Duration::from_secs(i); println!("I am thread {i}, sleeping for {worker_sleep_dur:?}"); thread::sleep(worker_sleep_dur); let maybe_value = init_once.try_init(|| { thread::sleep(time::Duration::from_secs(5)); println!("Took a second but we out here"); AnnounceDrop { value: format!("I am thread {i}, blazing 420"), } }); if let Some(AnnounceDrop { value }) = maybe_value { println!("Read {value:?} from {i}"); } else { println!("Thread {i} couldn't read value"); } }) }) .collect(); for handle in threads { handle.join().unwrap(); } } impl Drop for AnnounceDrop { fn drop(&mut self) { println!("Dropping value: {:?}", self.value); } }