Mutex应用场景
- 应用场景:当需要对共享数据进行独占式访问时使用。比如共享数据结构的修改操作,在同一时刻只允许一个线程对其进行修改,防止数据竞争。
- 优先选择情况:如果共享数据的读写操作都需要独占访问(即读操作也不允许并发),优先选择Mutex。例如银行账户余额的操作,无论是存款(写)还是查询余额(读),都需要防止其他线程同时操作,以保证数据一致性。
RwLock应用场景
- 应用场景:适用于读多写少的场景。允许多个线程同时进行读操作,但写操作必须是独占的。因为读操作不会修改数据,所以多个线程同时读不会产生数据竞争。
- 优先选择情况:当共享数据的读操作远远多于写操作时,优先选择RwLock。比如一个配置文件,启动时加载到内存,运行过程中读操作频繁,而写操作(修改配置)很少发生,这种场景适合用RwLock。
代码示例
use std::sync::{Arc, Mutex, RwLock};
use std::thread;
// 使用Mutex实现线程安全的读写共享数据结构
struct SharedDataMutex {
data: Mutex<i32>,
}
impl SharedDataMutex {
fn new() -> Self {
SharedDataMutex {
data: Mutex::new(0),
}
}
fn read(&self) -> i32 {
*self.data.lock().unwrap()
}
fn write(&self, value: i32) {
let mut guard = self.data.lock().unwrap();
*guard = value;
}
}
// 使用RwLock实现线程安全的读写共享数据结构
struct SharedDataRwLock {
data: RwLock<i32>,
}
impl SharedDataRwLock {
fn new() -> Self {
SharedDataRwLock {
data: RwLock::new(0),
}
}
fn read(&self) -> i32 {
*self.data.read().unwrap()
}
fn write(&self, value: i32) {
let mut guard = self.data.write().unwrap();
*guard = value;
}
}
fn main() {
// Mutex示例
let shared_mutex = Arc::new(SharedDataMutex::new());
let shared_mutex_clone = shared_mutex.clone();
let mut handles = Vec::new();
for _ in 0..10 {
let handle = thread::spawn(move || {
shared_mutex_clone.write(42);
let result = shared_mutex_clone.read();
println!("Mutex read result: {}", result);
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
// RwLock示例
let shared_rwlock = Arc::new(SharedDataRwLock::new());
let shared_rwlock_clone = shared_rwlock.clone();
let mut read_handles = Vec::new();
for _ in 0..10 {
let handle = thread::spawn(move || {
let result = shared_rwlock_clone.read();
println!("RwLock read result: {}", *result);
});
read_handles.push(handle);
}
let write_handle = thread::spawn(move || {
shared_rwlock.write().unwrap().replace(42);
});
write_handle.join().unwrap();
for handle in read_handles {
handle.join().unwrap();
}
}