面试题答案
一键面试RwLock比Mutex更适合的原因
- 读写并发优势:
Mutex
(互斥锁)只允许一个线程进入临界区,无论是读操作还是写操作。在大量线程频繁读取共享数据的场景下,若使用Mutex
,读操作之间也会相互阻塞,大大降低了并发性能。- 而
RwLock
(读写锁)允许多个线程同时进行读操作,因为读操作不会修改数据,不会产生数据竞争。只有当有线程进行写操作时,才会阻止其他读线程和写线程进入,这样可以显著提高读多写少场景下的并发性能。
- 写操作保护:
- 当偶尔有线程需要修改数据(写操作)时,
RwLock
能保证写操作的原子性和数据一致性。写操作时,会独占锁,阻止其他读写线程进入,确保数据修改的完整性。
- 当偶尔有线程需要修改数据(写操作)时,
使用RwLock确保数据一致性的示例(以Rust语言为例)
use std::sync::{Arc, RwLock};
use std::thread;
fn main() {
let data = Arc::new(RwLock::new(0));
let mut handles = vec![];
// 启动多个读线程
for _ in 0..10 {
let data_clone = data.clone();
let handle = thread::spawn(move || {
let read_data = data_clone.read().unwrap();
println!("Read data: {}", read_data);
});
handles.push(handle);
}
// 启动一个写线程
let data_clone = data.clone();
let write_handle = thread::spawn(move || {
let mut write_data = data_clone.write().unwrap();
*write_data += 1;
println!("Write data: {}", write_data);
});
handles.push(write_handle);
for handle in handles {
handle.join().unwrap();
}
}
在上述代码中:
- 使用
Arc<RwLock<T>>
来在多个线程间共享数据并实现线程安全。Arc
是原子引用计数智能指针,用于在多个线程间共享数据,RwLock
用于实现读写锁。 - 读线程通过
data.read().unwrap()
获取读锁,允许多个读线程同时读取数据。 - 写线程通过
data.write().unwrap()
获取写锁,此时会阻止其他读写线程进入,确保写操作的数据一致性。