spierce7
01/21/2020, 8:06 PMthis
isn’t frozen, and it seems like the property shouldn’t be frozen since it’s only ever touched by one thread.
2. I’m not seeing an exception when I attempt to mutate something that’s frozen. That seems odd.
3. I’m pretty sure I was seeing different behavior a month or so back (around Kotlinconf) where the property wasn’t frozen. Am I imagining this?fun main() {
val context1: CoroutineContext = newSingleThreadContext("Context1")
runBlocking(context1) {
println("Example 1")
val example1 = Example1(context1)
println(example1.example1())
println(example1.example1())
println(example1.example1())
println("Value: ${example1.value}")
println("Is Value Frozen : ${example1.value.isFrozen}")
println("Is Example1 Frozen: ${example1.isFrozen}")
}
}
object Background {
val context: CoroutineContext = newSingleThreadContext("Background") + NonCancellable
suspend fun asyncRandomInt(): Int = withContext(context) {
Random.nextInt()
}
}
class Example1(val context: CoroutineContext) {
var value = 0
fun example1() = GlobalScope.launch(context) {
val randomValue = Background.asyncRandomInt()
value += randomValue
}
}
Output:
Example 1
StandaloneCoroutine{Active}@322ff4d8
StandaloneCoroutine{Active}@322fefd8
StandaloneCoroutine{Active}@322fe748
Value: 0
Is Value Frozen : true
Is Example1 Frozen: false
Kris Wong
01/21/2020, 8:15 PMBackground.asyncRandomInt()
Dico
01/21/2020, 8:49 PMvalue
be a primitive type? Or does kotlin-native box all primitives?Sam Schilling
01/21/2020, 11:07 PMSome naturally immutable objects such asFor example, see the following:,kotlin.String
, and other primitive types, along with<http://kotlin.Int|kotlin.Int>
andAtomicInt
are frozen by default.AtomicReference
var test = false
print(test.isFrozen) // prints "true"
spierce7
01/21/2020, 11:21 PMKris Wong
01/21/2020, 11:23 PMspierce7
01/21/2020, 11:27 PMfun main() {
val context1: CoroutineContext = newSingleThreadContext("Context1")
runBlocking(context1) {
println("Example 1")
val example1 = Example1(context1)
example1.example1()
example1.example1()
example1.example1()
println("Data Value: ${example1.data.value}")
println("Is MutableData Frozen : ${example1.data.isFrozen}")
println("Is Example1 Frozen: ${example1.isFrozen}")
}
}
object Background {
val context: CoroutineContext = newSingleThreadContext("Background") + NonCancellable
suspend fun asyncRandomInt(): Int = withContext(context) {
5
}
}
data class MutableData(
var value: Int
)
class Example1(val context: CoroutineContext) {
val data = MutableData(0)
fun example1() = GlobalScope.launch(context) {
val randomValue = Background.asyncRandomInt()
data.value += randomValue
}
}
Example 1
Data Value: 0
Is MutableData Frozen : false
Is Example1 Frozen: false
Something is wrong though. Why is the data value 0
?Sam Schilling
01/21/2020, 11:29 PMKris Wong
01/21/2020, 11:29 PMspierce7
01/21/2020, 11:30 PMSam Schilling
01/21/2020, 11:30 PMdelay(500)
spierce7
01/21/2020, 11:31 PMfun main() {
val context1: CoroutineContext = newSingleThreadContext("Context1")
runBlocking(context1) {
println("Example 1")
val example1 = Example1(context1)
example1.example1()
example1.example1()
example1.example1()
println("Data Value: ${example1.data.value}")
println("Is MutableData Frozen : ${example1.data.isFrozen}")
println("Is Example1 Frozen: ${example1.isFrozen}")
}
}
object Background {
val context: CoroutineContext = newSingleThreadContext("Background") + NonCancellable
suspend fun asyncRandomInt(): Int = withContext(context) {
5
}
}
data class MutableData(
var value: Int
)
class Example1(val context: CoroutineContext) {
val data = MutableData(0)
suspend fun example1() = withContext(context) {
val randomValue = Background.asyncRandomInt()
data.value += randomValue
}
}
Example 1
Data Value: 15
Is MutableData Frozen : false
Is Example1 Frozen: false
Kris Wong
01/21/2020, 11:35 PMrunBlocking
is using the same context as your launch
Sam Schilling
01/21/2020, 11:35 PMvar foo = false
println("foo frozen: ${foo.isFrozen}")
foo = true
GlobalScope.launch {
var bar = false
println("bar frozen: ${bar.isFrozen}")
bar = true
println("set bar to $bar")
foo = false
println("set foo to $foo")
}
foo frozen: true
bar frozen: true
set bar to true
kotlin.native.concurrent.InvalidMutabilityException: mutation attempt of frozen kotlin.native.internal.Ref@64f13698
Kris Wong
01/21/2020, 11:37 PMSam Schilling
01/21/2020, 11:38 PMfreeze()
on primitive types and mutation attempts still succeed:
var foo = false
foo.freeze()
foo = true
println("foo set to $foo") // prints "foo set to true"
InvalidMutabilityException
in the above case but that doesn’t happen1.3.3-native-mt
)olonho
01/22/2020, 3:10 AMfoo
Kris Wong
01/22/2020, 2:05 PMDico
01/22/2020, 3:02 PMfoo
in a class. The compiler does that for you if you access it from another non-inlined or cross inlined scope/code blockKris Wong
01/22/2020, 3:05 PMDico
01/22/2020, 3:08 PMfoo
in a ref is the same on the jvm and probably javascript targets.Kris Wong
01/22/2020, 3:13 PMDico
01/22/2020, 3:14 PM