Java 添加一些随机打印修复了空白的问题
我试图从用户那里获得一些信息,这个GUI在单独的线程中与Kotlin(Jvm)一起运行。我这样做的尝试是(最低限度的工作示例,我无法摆脱UI)Java 添加一些随机打印修复了空白的问题,java,swing,kotlin,awt,Java,Swing,Kotlin,Awt,我试图从用户那里获得一些信息,这个GUI在单独的线程中与Kotlin(Jvm)一起运行。我这样做的尝试是(最低限度的工作示例,我无法摆脱UI) import java.awt.* import java.lang.Thread.sleep import javax.swing.* val board = Board() fun main() { EventQueue.invokeLater { ThreadAnimationEx().isVisible = true
import java.awt.*
import java.lang.Thread.sleep
import javax.swing.*
val board = Board()
fun main() {
EventQueue.invokeLater {
ThreadAnimationEx().isVisible = true
}
var test: String?=null
board.instruction = {
sleep(1000)
test= "test value"
println("Done")
}
while (test == null) {
//uncommenting this line makes this work
// sleep(100)
}
println("Finished with $test")
}
class ThreadAnimationEx() : JFrame() {
init {
add(board)
}
}
class Board : JPanel(), Runnable {
var instruction: (() -> Unit)? = null
private var animator: Thread? = null
override fun addNotify() {
super.addNotify()
animator = Thread(this)
animator!!.start()
}
public override fun paintComponent(g: Graphics) {
super.paintComponent(g)
Toolkit.getDefaultToolkit().sync()
}
override fun run() {
while (true) {
if (instruction != null) {
instruction!!.invoke()
instruction = null
}
sleep(10)
}
}
}
如果睡眠(100)未被注释掉,则程序正常工作,打印
Done
Finished with test value
如果没有这样的片段,那么我只得到
Done
这是kotlin或jvm中的错误吗?不,这是您程序中的错误。没有任何迹象表明
test
的值会改变,因此jvm完全有权使用缓存在寄存器中的值,而不是在while
循环中执行条件测试时从内存中获取值
您需要在test
变量上使用volatile
修饰符,或者使用为并发性设计的类型,例如
顺便说一句,调用
sleep
修复该问题的原因可能是因为发生了一些同步,导致内存障碍,迫使从内存中再次获取值。这与为什么打印也可以修复并发可见性问题类似,如中所述。不,这是您的pro中的一个错误没有任何迹象表明test
的值会改变,因此JVM完全有权使用缓存在寄存器中的值,而不是在while
循环中执行条件测试时从内存中获取值
您需要在test
变量上使用volatile
修饰符,或者使用为并发性设计的类型,例如
顺便说一句,调用sleep
修复它的原因可能是因为发生了一些同步,导致内存障碍,迫使从内存中再次获取值。这与为什么打印也可以修复并发可见性问题类似,如中所述