我想知道是否还有其他人遇到过这个问题。我的游戏中的这一部分代码依赖于 system.out.println 语句来工作。没有它,它将无法正常工作
while(isladder){
t = Map.tiles[(int) (Player.x + 15 + ScrollManager.xoffset) / 32][(int) ((Player.y ) + ScrollManager.yoffset) / 32];
if(t.row == 3 && t.col == 5){
ScrollManager.dy = -.5;
System.out.println(t.row);
}else{
ScrollManager.nogravity = false;
}
}
这是在有人按下向上键时启动的线程中。这是我正在制作的 2d Minecraft 游戏的梯子。如果没有 system.out.println 代码,玩家将继续漂浮在空中。有了它,玩家将像平常一样停在梯子的顶部
(更新)我只是通过添加 Thread.sleep(1) 来解决这个问题,以便它运行更顺畅
您遇到了线程内内存缓存的问题,这是一种优化技术,当 JIT 确定给定的内存块没有同步问题并且不需要与主内存同步时,JIT 使用该技术来加速您的程序。
相关问题:如何演示java多线程可见性问题? https://stackoverflow.com/questions/2787094/how-to-demonstrate-java-multithreading-visibility-problems
本质上发生的事情是这样的:
1)JIT加载类,并读入while()
环形
2) 的isladder
变量未声明volatile
,并且不通过任何检索synchronized
意味着,所以 JIT 认为:
“哦,这个变量基本上是本地的 - 我有线程缓存的值isladder
在本地,然后使用它,所以它运行得更快。”
当循环中不包含任何容易触发上下文切换的操作(例如 Thread.sleep()、System.out.println() I/O)时,缓存的值isladder
永远不会刷新。
虽然 Thread.sleep() 解决了表面问题,但它并没有解决代码中的根本问题,即缺乏对游戏状态的同步访问。您发布的这个线程似乎只是修改了滚动窗口,因此相当无害,但是当您使用线程控制动画对象、敌人等事物时,不良的多线程实践会导致自发的、看似随机的、不可预测的结果。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)