没有synchronized,rust怎么防并发?
学过Java的同学对synchronized肯定不陌生,那么rust里怎么办呢?
在Rust中,可以使用标准库提供的 std::sync::Mutex
来实现加锁功能。Mutex是互斥锁的一种实现,用于保护共享数据在并发访问时的安全性。
下面是一个简单的示例代码,展示了如何在Rust中使用Mutex进行加锁:
use std::sync::Mutex;
use std::thread;
fn main() {
// 创建一个共享数据
let counter = Mutex::new(0);
// 创建多个线程,每个线程对共享数据进行加锁和修改
let mut handles = vec![];
for _ in 0..10 {
let handle = thread::spawn(move || {
// 对共享数据加锁
let mut data = counter.lock().unwrap();
// 修改共享数据
*data += 1;
});
handles.push(handle);
}
// 等待所有线程完成
for handle in handles {
handle.join().unwrap();
}
// 输出最终结果
println!("Final value: {}", *counter.lock().unwrap());
}
在上述代码中,我们首先创建了一个共享数据 counter
,它被Mutex包裹起来。然后,我们创建了多个线程,并在每个线程中对共享数据进行加锁、修改和解锁操作。
在加锁时,我们使用 counter.lock().unwrap()
来获取Mutex的锁。这将会阻塞当前线程,直到锁可用。一旦获取到锁,我们就可以安全地修改共享数据。
在解锁时,Mutex会自动释放锁,允许其他线程获取锁并访问共享数据。
最后,我们输出最终结果。由于Mutex保证了对共享数据的安全访问,所以最终结果应该是正确的。
需要注意的是,在使用Mutex时,需要注意避免死锁和竞争条件。死锁可能发生在多个线程相互等待对方释放锁的情况下。竞争条件可能发生在多个线程同时修改共享数据时。
最后的最后留个作业,下面代码有问题吗? 评论区讨论
use std::sync::Mutex;
use std::thread;
fn main() {
// 创建两个共享数据
let data1 = Mutex::new(0);
let data2 = Mutex::new(0);
let handle1 = thread::spawn(move || {
// 对data1加锁
let _lock1 = data1.lock().unwrap();
println!("Thread 1 acquired lock on data1");
// 睡眠一段时间,模拟处理过程
thread::sleep_ms(1000);
let _lock2 = data2.lock().unwrap();
println!("Thread 1 acquired lock on data2");
});
let handle2 = thread::spawn(move || {
// 对data2加锁
let _lock2 = data2.lock().unwrap();
println!("Thread 2 acquired lock on data2");
// 睡眠一段时间,模拟处理过程
thread::sleep_ms(1000);
let _lock1 = data1.lock().unwrap();
println!("Thread 2 acquired lock on data1");
});
handle1.join().unwrap();
handle2.join().unwrap();
}