Hi, I'm using OnceLock, Arc and Mutex to create a global singleton with thread safety, and it works fine already:
// An example
fn get_instance() -> &'static Arc<Mutex<String>> {
static INSTANCE: OnceLock<Arc<Mutex<String>>> = OnceLock::new();
INSTANCE.get_or_init(|| {
Arc::new(Mutex::new(String::new()))
})
}
// In some other thread
let lock = get_instance().lock().unwrap();
As the rust document says, Arc is an atomic reference counter for sharing ownerships, but in the example above it is already static, the lifetime is the whole program. I think here tracing the reference counter is unnecessary.
Can I replace OnceLock<Arc<Mutex<String>>> to OnceLock<Mutex<String>> so just make the get_instance function returns a &'static Mutex<String>?
If it is going to be around for the whole program anyway then you aren't really gaining anything from having Arc in there so you can just have a OnceLock<Mutex<String>> and pass references around. If you do that then you also don't need the OnceLock (both Mutex::new() and String::new() are const), so you can just have Mutex<String>.
The OnceLock might still be useful, though, if you need one-time initialization that can’t be done with const— Especially if the empty string is a valid value and not just a sentinel for being uninitialized.