Start here. This is the direct spoken answer to practice first.
Why this question matters
Exactly-once initialization looks simple until concurrent callers, failure, retry, and disposal are involved. .NET already provides safer mechanisms than a hand-written boolean and nullable field.
For synchronous initialization I would first consider normal static initialization or Lazy<T>, because both express one-time construction without a manual race. Callers use lazy.Value, and the runtime coordinates concurrent access according to the selected thread-safety mode. I would avoid if (_instance == null) _instance = Create() because two threads can both pass the check. The initialized object must also be safe for the way multiple callers will use it; safe construction does not make later mutation thread-safe.