Merge pull request #1324 from asthetik/optimize

Optimize sample code
pull/1344/head
Sunface 10 months ago committed by GitHub
commit 040412af11
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -413,20 +413,30 @@ use std::cell::Cell;
use std::thread; use std::thread;
let tls = Arc::new(ThreadLocal::new()); let tls = Arc::new(ThreadLocal::new());
let mut v = vec![];
// 创建多个线程 // 创建多个线程
for _ in 0..5 { for _ in 0..5 {
let tls2 = tls.clone(); let tls2 = tls.clone();
thread::spawn(move || { let handle = thread::spawn(move || {
// 将计数器加1 // 将计数器加1
// 请注意,由于线程 ID 在线程退出时会被回收,因此一个线程有可能回收另一个线程的对象
// 这只能在线程退出后发生,因此不会导致任何竞争条件
let cell = tls2.get_or(|| Cell::new(0)); let cell = tls2.get_or(|| Cell::new(0));
cell.set(cell.get() + 1); cell.set(cell.get() + 1);
}).join().unwrap(); });
v.push(handle);
}
for handle in v {
handle.join().unwrap();
} }
// 一旦所有子线程结束,收集它们的线程局部变量中的计数器值,然后进行求和 // 一旦所有子线程结束,收集它们的线程局部变量中的计数器值,然后进行求和
let tls = Arc::try_unwrap(tls).unwrap(); let tls = Arc::try_unwrap(tls).unwrap();
let total = tls.into_iter().fold(0, |x, y| x + y.get()); let total = tls.into_iter().fold(0, |x, y| {
// 打印每个线程局部变量中的计数器值发现不一定有5个线程
// 因为一些线程已退出,并且其他线程会回收退出线程的对象
println!("x: {}, y: {}", x, y.get());
x + y.get()
});
// 和为5 // 和为5
assert_eq!(total, 5); assert_eq!(total, 5);

Loading…
Cancel
Save