面试题答案
一键面试- 引入必要的包:
在Rust中,
Arc
(原子引用计数)和Mutex
(互斥锁)来自标准库,所以无需额外引入外部包。
use std::sync::{Arc, Mutex};
use std::thread;
- 创建线程安全的
Vec<T>
: 使用Arc
和Mutex
来包装Vec<T>
。Arc
用于在多个线程间共享数据,Mutex
用于保证同一时间只有一个线程能访问数据。
let shared_vec = Arc::new(Mutex::new(vec![1, 2, 3]));
这里创建了一个Arc
包裹着Mutex
,而Mutex
又包裹着一个Vec<i32>
。
- 在多线程中使用:
let mut handles = vec![];
for _ in 0..3 {
let clone = shared_vec.clone();
let handle = thread::spawn(move || {
let mut vec = clone.lock().unwrap();
vec.push(4);
println!("{:?}", vec);
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
let clone = shared_vec.clone();
:由于Arc
是引用计数的,clone
方法会增加引用计数,使得每个线程都能持有一个指向共享数据的Arc
。let mut vec = clone.lock().unwrap();
:这里调用lock
方法尝试获取Mutex
的锁。如果获取成功(返回Result
类型,unwrap
方法在成功时返回内部值,失败时会panic
),就可以对Vec
进行操作。vec.push(4);
:向Vec
中添加一个元素。println!("{:?}", vec);
:打印当前Vec
的内容。- 最后通过
join
方法等待所有线程执行完毕。
完整代码如下:
use std::sync::{Arc, Mutex};
use std::thread;
fn main() {
let shared_vec = Arc::new(Mutex::new(vec![1, 2, 3]));
let mut handles = vec![];
for _ in 0..3 {
let clone = shared_vec.clone();
let handle = thread::spawn(move || {
let mut vec = clone.lock().unwrap();
vec.push(4);
println!("{:?}", vec);
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
}