1 use std::sync::{Arc, RwLock};
5 pub struct ConcurrentCounter(Arc<RwLock<usize>>);
7 impl ConcurrentCounter {
8 // The constructor should not be surprising.
9 pub fn new(val: usize) -> Self {
10 ConcurrentCounter(Arc::new(RwLock::new(val)))
13 pub fn increment(&self, by: usize) {
14 let mut counter = self.0.write().unwrap_or_else(|e| e.into_inner());
15 *counter = *counter + by;
18 pub fn compare_and_inc(&self, test: usize, by: usize) {
19 let mut counter = self.0.write().unwrap_or_else(|e| e.into_inner());
25 pub fn get(&self) -> usize {
26 let counter = self.0.read().unwrap_or_else(|e| e.into_inner());
31 // Now our counter is ready for action.
33 let counter = ConcurrentCounter::new(0);
35 // We clone the counter for the first thread, which increments it by 2 every 15ms.
36 let counter1 = counter.clone();
37 let handle1 = thread::spawn(move || {
40 counter1.increment(2);
44 // The second thread increments the counter by 3 every 20ms.
45 let counter2 = counter.clone();
46 let handle2 = thread::spawn(move || {
49 counter2.increment(3);
53 // Now we want to watch the threads working on the counter.
56 println!("Current value: {}", counter.get());
59 // Finally, wait for all the threads to finish to be sure we can catch the counter's final value.
60 handle1.join().unwrap();
61 handle2.join().unwrap();
62 println!("Final value: {}", counter.get());