use std::sync::{Arc, Mutex, RwLock, RwLockWriteGuard};
use std::thread;
use std::collections::HashMap;
use std::fmt::{Formatter, Error};
use lazy_static::lazy_static;
struct Counter {
count: i32,
}
struct BigStruct {
counter: Option<Counter>,
}
impl BigStruct {
fn increment(&mut self) {
match self.counter {
Some(ref mut counter) => {
counter.count += 1;
},
None => {},
}
}
}
impl std::fmt::Display for BigStruct {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
match self.counter {
Some(ref counter) => {
write!(f, "count: {}", counter.count)
},
None => {
write!(f, "count: {}", 0)
},
}
}
}
lazy_static! {
static ref MAP_COUNTER: RwLock<HashMap<String, Arc<Mutex<BigStruct>>>> = {
let map = HashMap::new();
RwLock::new(map)
};
}
fn get_global_counter(key: String) -> Arc<Mutex<BigStruct>> {
let mut map: RwLockWriteGuard<HashMap<String, Arc<Mutex<BigStruct>>>> = MAP_COUNTER.try_write().unwrap();
if !map.contains_key(&key.clone()) {
let big_struct = BigStruct {
counter: Some(Counter{ count: 0 }),
};
map.insert(key.clone(), Arc::new(Mutex::new(big_struct)));
}
let writer = map.get(&key.clone()).unwrap();
Arc::clone(writer)
}
fn main() {
let mut handles = vec![];
let key = String::from("1");
let counter = get_global_counter(key);
for _ in 0..10 {
let counter = Arc::clone(&counter);
let handle = thread::spawn(move || {
let mut big_struct = counter.lock().unwrap();
// thread::sleep(std::time::Duration::from_secs(1));
big_struct.increment();
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap_or_default();
}
println!("Result: {}", *counter.lock().unwrap());
}
More than 5 years have passed since last update.
Register as a new user and use Qiita more conveniently
- You get articles that match your needs
- You can efficiently read back useful information
- You can use dark theme