Метод call_once
Метод call_once класса Once гарантирует,
что переданная в него функция будет выполнена
ровно один раз, даже если метод вызывается
из нескольких потоков одновременно. Все последующие
вызовы не выполняют функцию повторно, а просто
возвращают управление. Параметром метод принимает
замыкание FnOnce, которое нужно выполнить
единожды. Метод не возвращает значения и требует,
чтобы объект Once был доступен по ссылке.
Синтаксис
once.call_once(|| {
// код, выполняемый один раз
});
Пример
Давайте создадим объект Once и вызовем
call_once несколько раз подряд, чтобы убедиться,
что функция выполняется только при первом вызове:
use std::sync::Once;
fn main()
{
let once = Once::new();
once.call_once(|| {
println!("init");
});
once.call_once(|| {
println!("init");
});
once.call_once(|| {
println!("init");
});
}
Результат выполнения кода:
"init"
Пример
Давайте используем Once совместно с несколькими
потоками, чтобы показать, что инициализация выполняется
ровно один раз:
use std::sync::{Arc, Once};
use std::thread;
fn main()
{
let once = Arc::new(Once::new());
let mut handles = vec![];
for _ in 0..5 {
let once_clone = Arc::clone(&once);
let handle = thread::spawn(move || {
once_clone.call_once(|| {
println!("init once");
});
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
}
Результат выполнения кода:
"init once"
Пример
Давайте сохраним результат однократной инициализации
в общий ресурс и выведем его после выполнения
call_once:
use std::sync::{Arc, Mutex, Once};
fn main()
{
let once = Once::new();
let data = Arc::new(Mutex::new(0));
let data_clone = Arc::clone(&data);
once.call_once(|| {
let mut value = data_clone.lock().unwrap();
*value = 12345;
});
println!("{}", *data.lock().unwrap());
}
Результат выполнения кода:
12345
Смотрите также
-
класс
Once,
который гарантирует однократное выполнение инициализации -
метод
new,
который создаёт новый объект Once -
класс
OnceLock,
который позволяет однократно записать значение -
метод
get_or_init,
который возвращает значение или инициализирует его один раз