X-Git-Url: https://git.ralfj.de/rust-101.git/blobdiff_plain/ccf679adb3790903849f7d85b970b67582220952..ab7f9b241429bd675b437d2437799de75d2f409b:/solutions/src/counter.rs?ds=sidebyside diff --git a/solutions/src/counter.rs b/solutions/src/counter.rs index 265fb99..acf8293 100644 --- a/solutions/src/counter.rs +++ b/solutions/src/counter.rs @@ -1,8 +1,9 @@ use std::sync::{Arc, RwLock}; use std::thread; +use std::time::Duration; #[derive(Clone)] -struct ConcurrentCounter(Arc>); +pub struct ConcurrentCounter(Arc>); impl ConcurrentCounter { // The constructor should not be surprising. @@ -11,12 +12,19 @@ impl ConcurrentCounter { } pub fn increment(&self, by: usize) { - let mut counter = self.0.write().unwrap(); + let mut counter = self.0.write().unwrap_or_else(|e| e.into_inner()); *counter = *counter + by; } + pub fn compare_and_inc(&self, test: usize, by: usize) { + let mut counter = self.0.write().unwrap_or_else(|e| e.into_inner()); + if *counter == test { + *counter += by; + } + } + pub fn get(&self) -> usize { - let counter = self.0.read().unwrap(); + let counter = self.0.read().unwrap_or_else(|e| e.into_inner()); *counter } } @@ -29,7 +37,7 @@ pub fn main() { let counter1 = counter.clone(); let handle1 = thread::spawn(move || { for _ in 0..10 { - thread::sleep_ms(15); + thread::sleep(Duration::from_millis(15)); counter1.increment(2); } }); @@ -38,14 +46,14 @@ pub fn main() { let counter2 = counter.clone(); let handle2 = thread::spawn(move || { for _ in 0..10 { - thread::sleep_ms(20); + thread::sleep(Duration::from_millis(20)); counter2.increment(3); } }); // Now we want to watch the threads working on the counter. for _ in 0..50 { - thread::sleep_ms(5); + thread::sleep(Duration::from_millis(5)); println!("Current value: {}", counter.get()); }