Если вы не получите RLock для чтения syncProducer
, это гонка данных, поскольку другая программа может обновить ее.
Если вы предполагаете, что чтение / запись в переменные-указатели являются атомарными, это выглядит безвредным - быстрое чтение syncProducer
никогда не приведет к некорректному поведению. Если вы не сделаете это атомарное предположение, чтение может выдать только некоторые байты указателя, если вам не повезло, и ваша программа потерпит крах.
Это может быть или не быть возможным в зависимости от используемой архитектуры, размера машинного слова, версии компилятора и т. Д. Но RLock
избегает любой заботы.
Вместо того, чтобы явно возиться с RWLocks, вероятно, лучше использовать это (предполагая, что цель состоит в том, чтобы лениво инициализировать переменную):
var (
syncOnce sync.Once
syncProducerInternal *syncProducerType
)
func syncProducer() *syncProducerType {
syncOnce.Do(func() { syncProducerInternal = createSyncKafkaProducer() })
return syncProducerInternal
}
Тогда код, которому нужен производитель синхронизации, может вызвать функцию syncProducer()
, чтобы получить его, и никогда не видеть нулевой указатель.