Kotlin 同步内联

标签 kotlin

您是否知道 Kotlin 中无法同步内联函数?我找不到任何相关文档。

假设您有一个带有同步方法的类;

/**
 * Allows modifying the value in a synchronized way so that the get() and set() are atomic.
 *
 * Note: anything synchronized cannot be `inline`.
 */
@Synchronized fun safeSet(calculateNewValue: (T) -> T) {
    set(calculateNewValue(get()))
}

当此函数内联时,此测试失败,当它未内联时,则通过。

@Test
fun `safeSet - is synchronized`() {
    val insideSet = AtomicInteger()
    val threadsRun = CountDownLatch(2)
    val t1 = Thread({
        threadsRun.countDown()
        sut.safeSet { currentValue: Int ->
            insideSet.incrementAndGet()
            try {
                Thread.sleep(100000)
            } catch (interrupted: InterruptedException) {
                BoseLog.debug(interrupted)
            }
            currentValue + 1
        }
    })
    t1.start()

    val t2 = Thread({
        threadsRun.countDown()
        sut.safeSet { currentValue: Int ->
            insideSet.incrementAndGet()
            try {
                Thread.sleep(100000)
            } catch (interrupted: InterruptedException) {
                BoseLog.debug(interrupted)
            }
            currentValue + 2
        }
    })
    t2.start()

    threadsRun.await()
    Thread.sleep(100)
    assertEquals(1, insideSet.get())
    t1.interrupt()
    t2.interrupt()
    Thread.sleep(100)
    assertEquals(2, insideSet.get())
}

最佳答案

@Synchronized 注释告诉编译器在方法上生成 ACC_SYNCHRONIZED 标志。内联函数不会编译为方法,因此注释确实被忽略。

有一个open issue在 Kotlin 中可以更好地处理这种情况。

关于Kotlin 同步内联,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53089859/

相关文章:

java - 在 RXJava android 中为线程设置名称

android - Gradle 构建任务 :app:dataBindingGenBaseClassesShopDevDebug Failed

android - 使用 Kotlin 将运行时边距设置为任何 View

collections - Kotlin 将带有可空值的列表转换为不带可空值的 HashMap

android.view.View.systemUiVisibility 已弃用。什么是替代品?

mysql - Hibernate 奇怪的行为与 @OneToMany 和更新

kotlin - 我想将数据传递给弹出对话框

kotlin - 在协程处理程序和 try-catch block 中处理异常

android - 由于未知的下载问题,同步 Gradle 失败

kotlin - 如何选择Kotlin派生类中要覆盖的Java重载?