Обновленный ответ
Быстрый ответ - поместить этот код в актера, и вам не нужно беспокоиться о синхронизации.
Если вы используете Akka Actors, вам никогда не нужно выполнять собственную синхронизацию потоков с использованием низкоуровневых примитивов. Весь смысл модели актора состоит в том, чтобы ограничить взаимодействие между потоками только передачей асинхронных сообщений. Это обеспечивает всю необходимую вам синхронизацию потоков и гарантирует, что субъект обрабатывает одно сообщение за раз однопоточным способом.
У вас определенно не должно быть функции, к которой одновременно могут обращаться несколько потоков, создающих одноактный актер. Просто создайте актера, когда у вас есть нужная информация, и передайте ActorRef
любым другим акторам, которым это нужно, с помощью внедрения зависимости или сообщения. Или создайте актера в начале и инициализируйте его при поступлении первого сообщения (используйте context.become
для управления состоянием актера).
Оригинальный ответ
Самое простое решение - просто использовать lazy val
для хранения вашего экземпляра foo
:
class Foo {
lazy val foo = {
println("called")
/* Side Effects */
"foo"
}
}
Это создаст foo
при первом использовании и после этого просто вернет то же значение.
Если по какой-либо причине это невозможно, используйте AtomicInteger
, инициализированный для 0
, а затем позвоните incrementAndGet
. Если это возвращает 1
, то это первый проход через этот код, и вы можете позвонить foo
.
Пояснение:
Атомарные операции, такие как compareAndSet
, требуют поддержки из набора команд ЦП, и современные процессоры имеют отдельные атомарные инструкции для таких операций. В некоторых случаях (например, строка кэша поддерживается исключительно этим процессором) операция может быть очень быстрой. В других случаях (например, строка кэша также в кеше другого процессора) операция может быть значительно медленнее и влиять на другие потоки.
В результате процессор должен удерживать новое значение перед выполнением атомарной инструкции. Таким образом, значение должно быть вычислено до того, как станет известно, нужно ли оно или нет.