RwLock允许同一时间有多个读对象或只存在一个写对象。在多线程中,如果要多个读或多个写,需要Arc::RwLock 。
use std::thread;
use std::sync::{Arc, Mutex};
use std::time;
use std::collections::{HashMap};
use std::sync::RwLock;
#[macro_use]
extern crate lazy_static;
lazy_static! {
static ref HASHMAP: HashMap<u32,String> = {
let mut m = HashMap::new();
m.insert(0, "foo".into());
m.insert(1, "bar".into());
m.insert(2, "baz".into());
m
};
}
fn main(){
// 非全局式
{
let mut hp = HashMap::new();
hp.insert("1".to_string(),1);
let lock_1 = Arc::new(RwLock::new(hp));//多个线程读写
{
println!("single thread write =>");
let mut w = lock_1.write().unwrap();
(*w).insert("2".to_string(),2);
}
{
println!(" single thread read =>");
let r = lock_1.read().unwrap();
println!("r:{:?} {:?}",1,*r);
}
{
println!("multi readers => ");
for i in 0..10{
let lock = lock_1.clone();
thread::spawn(move ||{
let r = lock.read().unwrap();
println!("r:{:?} {:?}",i,*r);
});
}
}
{
println!("multi writers => ");
for i in 0..10{
let lock = lock_1.clone();
thread::spawn(move ||{
let mut _w = lock.write().unwrap();
(*_w).insert(i.to_string(),i*i);
println!(":{:?} {:?}",i,*_w);
});
}
}
}
println!("RwLock=> mode");
//全局式
{
let lock_1 = RwLock::new(HASHMAP.clone());//一个写,多个读
// .read(); .write()
{
println!("single thread write =>");
let mut w = lock_1.write().unwrap();
(*w).insert(2,"2".to_string());
println!("*w =>{:?}",*w);
}
{
println!(" single thread read =>");
let r = lock_1.read().unwrap();
println!("r:{:?} {:?}",1,r);
}
}
std::thread::sleep(std::time::Duration::from_secs(100));
}
如果没有Arc,比如下面:
use lazy_static::lazy_static;
use std::{ sync::RwLock, thread};
// 使用 lazy_static 初始化复杂的结构
lazy_static! {
// 使用 Mutex / RwLock 来提供安全的并发写访问
static ref lock: RwLock<Vec<(&'static str, &'static [u8])>> = RwLock::new(Vec::new());
}
fn main() {
let mut handles = Vec::new();
let t1 = thread::spawn(move || {
let mut w = lock.write().unwrap();
(*w).push(("hello", b"world"));
});
handles.push(t1);
let t2 = thread::spawn(move || {
let mut w = lock.write().unwrap();
(*w).push(("heoooooo", b"world"));
});
handles.push(t2);
for handle in handles{
handle.join().unwrap();
}
println!("store: {:?}", lock.read().unwrap());
}
由于线程的随机性,lock中的数据里面的先后顺序可能是不一致的。