Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/183.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么会这样?(在主线程中生成值并在Android中的其他后台线程中使用)_Java_Android_Multithreading_Kotlin - Fatal编程技术网

Java 为什么会这样?(在主线程中生成值并在Android中的其他后台线程中使用)

Java 为什么会这样?(在主线程中生成值并在Android中的其他后台线程中使用),java,android,multithreading,kotlin,Java,Android,Multithreading,Kotlin,据我所知,线程在本地缓存中复制变量。 我所做的是,在主线程中获取值,然后在其他后台(渲染器)线程中使用它们。像这样- class MySurfaceView ... { private var someValue = 0 // Called from the main thread fun updateValue() { someValue++ } fun render() { Thread {

据我所知,线程在本地缓存中复制变量。 我所做的是,在主线程中获取值,然后在其他后台(渲染器)线程中使用它们。像这样-

class MySurfaceView ... {
    private var someValue = 0

    // Called from the main thread
    fun updateValue() {
        someValue++
    }
    
    fun render() {
        Thread {
            // Here someValue variable is consumed
            // and it's always up to date.
            ....
        }.start()
    }
}
因此,在传递给render()内启动的线程的runnable中,“someValue”始终是最新的,我甚至没有将其标记为volatile。如果线程将变量复制到本地缓存,那么为什么会发生这种情况?是否因为外部类的隐式引用被保留,而值来自于外部类(如果这是真的,那么在这种情况下,如果我有一个生成器和多个使用者线程,那么不将仅由生成器线程更新的字段标记为volatile是否总是安全的?因为volatile上的读/写操作是昂贵的)? 当我启动一个协同程序并尝试访问其中的“someValue”时,同样的事情也会发生

线程在本地缓存中复制变量

事实并非如此,这解释了您的发现。基本上,您混淆了实现可能行使的自由与规范提供的保证。Java内存模型(Kotlin也遵循该模型)简单地说,让实现可以自由地对未通过同步操作共享的状态执行任何操作。它可以将其存储在堆栈或寄存器中,也可以与堆上的原始状态一起工作

一个特别相关的细节是
println()
是一个
synchronized
方法,因此如果在实际代码中,您在两个线程中都有
println
以查看发生了什么,那么您引入了同步,从而使结果正确

另一方面,以这种自由为例,很容易看到一个程序

Thread 1:

var runningFlag = true

while (runningFlag) {}

Thread 2:

sleep(1000)
runningFlag = false

线程1很可能永远执行下去,甚至被编译成类似于
currentThread().join()
——不做实际工作,但永远不会完成。

“据我所知,线程在本地缓存中复制变量”--不。我仍然感到困惑。我知道变量并不总是复制到本地缓存。但是,在我问题中的示例这样的情况下不使用volatile或引入同步是安全的还是不安全的?它不安全。变量必须是volatile的,以确保另一个线程观察到它的更新。这就是我的代码片段的目的。