Am I correct in thinking it’s possible for `by laz...
# getting-started
c
Am I correct in thinking it’s possible for
by lazy(LazyThreadSafetyMode.NONE)
to NPE in the case where two threads race to initialize the value? I thought the worst case was multiple creations 😕
Copy code
override val value: T
        get() {
            if (_value === UNINITIALIZED_VALUE) {
                _value = initializer!!()
                initializer = null
            }
            @Suppress("UNCHECKED_CAST")
            return _value as T
        }
EG: Both Thread A and Thread B enter the
if
condition before
_value
is set, one of the threads sets
_value
and then nulls the
initializer
before the second thread sets value, resulting in a NPE
I suppose what I want is
PUBLICATION
?
👌 1
x
In your example, wouldn't the call to
by lazy { }
in the second thread just return the memoized value without calling the initializer function?
l
This is the code for how a lazy getter works. I have seen NPEs when accessing lazy vars in weird ways (especially when 2 lazy vars accidentally depend on each other). It should NPE in the following example:
Copy code
Thread 1             Thread 2
check initialized    check initialized
call initializer     OS schedules other work
set _value
nullify initializer
return value        call initializer (NPE)
You'll want to set up some sort of a thread safe guard for any potential uses, or instead, use the variable once early on to make sure it gets initialized properly.
x
That’s interesting to know. I hadn’t seen any case like that before. Not a 100% sure, but I think that using
synchronized
could fix it: