gpt4 book ai didi

kotlin - Kotlin synchronized() 是否不锁定基本类型?

转载 作者:行者123 更新时间:2023-12-04 16:24:21 24 4
gpt4 key购买 nike

class Notification(val context: Context, title: String, message: String) {
private val channelID = "TestMessages"

companion object ID {
var s_notificationID = -1
}

init {
var notificationID = -1
synchronized(s_notificationID) {
if (++s_notificationID == 0)
createNotificationChannel()
notificationID = s_notificationID
}
以上是从两个线程同时调用的。 createNotificationChannel() 中的断点清楚地表明,有时 s_notificationID等于 1。
但是,如果我改变 synchronized(s_notificationID)synchronized(ID)那么它似乎锁定得很好。
synchronized() 是否不锁定基本类型?如果是这样,为什么要编译?

最佳答案

查看生成的 JVM 字节码表明 ID例子看起来像

synchronized(ID) { ... }
这是你所期望的。然而, s_notificationID示例看起来更像
synchronized(Integer.valueOf(s_notificationID)) { ... }
在 Java 中,我们只能同步对象,而不能同步原语。 Kotlin 基本上消除了这种区别,但看起来您已经找到了一个实现仍然渗透的地方。自 s_notificationIDint就 JVM 而言(因此,不是对象)而是 synchronized期望一个对象,Kotlin 足够“聪明”,可以将值包装在 Integer.valueOf 中一经请求。对您来说不幸的是,这会产生非常不一致的结果, because

This method will always cache values in the range -128 to 127, inclusive, and may cache other values outside of this range.


因此,对于较小的数字,这可以保证锁定内存中您无法控制的某些缓存对象。对于较大的对象,它可能是一个新对象(因此总是未锁定),或者它可能会再次出现在您手中的缓存对象上。
这里的教训似乎是:不要同步原始类型。

关于kotlin - Kotlin synchronized() 是否不锁定基本类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68423781/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com