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
}
cdurham
08/11/2023, 7:20 PM
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
cdurham
08/11/2023, 7:22 PM
I suppose what I want is
PUBLICATION
?
👌 1
x
xoangon
08/11/2023, 9:59 PM
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
Landry Norris
08/11/2023, 11:33 PM
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)
Landry Norris
08/11/2023, 11:34 PM
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
xoangon
08/12/2023, 7:20 AM
That’s interesting to know. I hadn’t seen any case like that before. Not a 100% sure, but I think that using