- 使用
Arc
和Mutex
实现线程安全:
Arc
(原子引用计数)用于在多个线程间共享数据,Mutex
(互斥锁)用于保护共享数据,防止数据竞争。
- 对于自定义结构体
Value
,它内部包含Vec<i32>
,移动语义会自动处理Vec
的内存管理。
- 关键代码片段:
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
use std::thread;
struct Value {
data: Vec<i32>,
}
fn main() {
let shared_map = Arc::new(Mutex::new(HashMap::new()));
let mut handles = vec![];
for _ in 0..10 {
let map_clone = Arc::clone(&shared_map);
let handle = thread::spawn(move || {
let mut map = map_clone.lock().unwrap();
let key = "test_key".to_string();
if let Some(value) = map.remove(&key) {
// 这里可以对value进行移动操作,因为它实现了`Move`语义
let new_data = value.data;
// 处理new_data...
} else {
let new_value = Value { data: vec![1, 2, 3] };
map.insert(key, new_value);
}
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
}
- 代码解释:
- 首先定义了
Value
结构体,它包含Vec<i32>
,满足移动语义。
- 创建了一个
Arc<Mutex<HashMap<String, Value>>>
类型的shared_map
,Arc
使得HashMap
可以在多线程间共享,Mutex
保护HashMap
在多线程访问时的数据一致性。
- 在每个线程中,通过
map_clone.lock().unwrap()
获取对HashMap
的可变引用。这里使用unwrap
简单处理lock
可能返回的错误,实际应用中可以更优雅地处理。
- 使用
map.remove
尝试从HashMap
中移除值,如果成功则获取到Value
实例,并移动其内部的data
字段。如果失败,则插入一个新的Value
实例。
- 最后,等待所有线程完成。这样通过
Arc
和Mutex
的组合,实现了多线程环境下对HashMap
的线程安全读写,同时遵循移动语义。