面试题答案
一键面试- 引入必要的包:
use std::sync::{Arc, atomic::{AtomicBool, Ordering}};
- 定义
ComplexObject
结构体:struct ComplexObject { // 这里假设`ComplexObject`有一些字段,例如 data: String, } impl ComplexObject { fn new() -> Self { ComplexObject { data: "Initial data".to_string(), } } }
- 使用
AtomicBool
和Arc
实现延迟初始化:struct LazyComplexObject { initialized: AtomicBool, inner: Option<Arc<ComplexObject>>, } impl LazyComplexObject { fn new() -> Self { LazyComplexObject { initialized: AtomicBool::new(false), inner: None, } } fn get(&self) -> Arc<ComplexObject> { if self.initialized.load(Ordering::SeqCst) { self.inner.as_ref().unwrap().clone() } else { let new_obj = Arc::new(ComplexObject::new()); if self.initialized.compare_and_swap(false, true, Ordering::SeqCst) { // 如果在比较并交换时已经被其他线程初始化了,就丢弃当前创建的对象 drop(new_obj); self.inner.as_ref().unwrap().clone() } else { self.inner = Some(new_obj.clone()); new_obj } } } }
解释:
LazyComplexObject
结构体包含一个AtomicBool
类型的initialized
字段,用于标记ComplexObject
是否已经初始化,以及一个Option<Arc<ComplexObject>>
类型的inner
字段,用于存储初始化后的ComplexObject
。LazyComplexObject::new
方法初始化initialized
为false
,inner
为None
。LazyComplexObject::get
方法首先检查initialized
是否为true
,如果是则直接返回已初始化的ComplexObject
。如果initialized
为false
,则创建一个新的ComplexObject
。然后使用compare_and_swap
方法尝试将initialized
从false
设置为true
。如果设置成功,表示当前线程成功初始化对象,将新创建的对象存入inner
并返回。如果设置失败,说明其他线程已经完成初始化,丢弃当前创建的对象并返回已有的对象。这种方式保证了在多线程环境下ComplexObject
只会被初始化一次且线程安全。