Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/377.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 如何确保一个线程得到另一个线程修改的最新变量?_Java_Multithreading - Fatal编程技术网

Java 如何确保一个线程得到另一个线程修改的最新变量?

Java 如何确保一个线程得到另一个线程修改的最新变量?,java,multithreading,Java,Multithreading,好的,我正在做一个2D游戏,所有的地图都用2D数组表示。我有很多方法,可以根据地图中已有的内容修改地图。因此,在实现了一些特性之后,FPS正在降低,所以我决定尝试使用多个线程来提高速度(好的事情,不是吗?) 我制作了3个线程来完成这项工作,一个用于绘制和处理事件,一个用于更新映射的基本部分,另一个用于更新另一组变量。问题是,当我启动所有3个线程时,它会绘制,但不会更新。当我从绘制线程调用方法时,它会更新。我通过在运行时添加“System.exit(0);”来测试第一个更新线程,否则它不会启动。我

好的,我正在做一个2D游戏,所有的地图都用2D数组表示。我有很多方法,可以根据地图中已有的内容修改地图。因此,在实现了一些特性之后,FPS正在降低,所以我决定尝试使用多个线程来提高速度(好的事情,不是吗?)

我制作了3个线程来完成这项工作,一个用于绘制和处理事件,一个用于更新映射的基本部分,另一个用于更新另一组变量。问题是,当我启动所有3个线程时,它会绘制,但不会更新。当我从绘制线程调用方法时,它会更新。我通过在运行时添加“System.exit(0);”来测试第一个更新线程,否则它不会启动。我还试图在更新线程的run方法中直接手动更改贴图的一个平铺,但没有任何效果。因此,我得出结论,运行已执行,变量已修改。所以我想画家使用的变量可能不是更新的

所有变量都在一个单独的类中,是静态的(是这样吗?),由一个对象访问,但后来我用代码“NameOfClass.variableName”将其更改为“直接”访问(IDE建议)

差点忘了提到,事件(在使用paint()方法的类中)修改了映射,这部分确实有效


我不知道该怎么办,有人有主意了吗?

您需要将有问题的变量标记为
volatile
,这将阻止编译器在局部变量中缓存副本,而不是每次读取/写入实际值。

我认为问题在于竞争条件。随着其他访问的进行,变量修改可能会“延迟”(几百纳秒?),但最终还是会发生。在这种情况下,我不认为
volatile
或类似的东西会有什么不同,因为线程同步的顺序应该不重要。如果是的话,你有更大的事情要担心。此外,我认为您的术语可能有点混乱——我无法真正理解与代码相关的线程问题


如果需要硬同步,可以建立资源“围栏”(同步块),并将资源访问保持在这些围栏内,这样就不会出现竞争条件。你建立交易的本质是,当你在操作这些变量时,没有任何东西可以进入围栏。

我的术语有很多混乱。问题是,paint方法没有绘制更新方法修改的变量,它似乎绘制了默认变量,或者在同一类中修改的变量。此外,我不确定您的游戏是否足够复杂,足以保证多线程。此外,事件处理当然不保证有一个单独的线程——这些线程通常是回调,因此您可以使用事件详细信息设置一个结构,并在主事件循环(可能是命令队列)上获取它。事件没有单独的线程,它们只是与paint()方法在同一个类中。另外,你知道更好的提高2D游戏性能的方法吗?我以每秒30帧的速度运行,功能量很低,所以它会变慢。我见过类似的游戏比我在C中以60 FPS的速度玩的游戏多3倍(我知道这不一样,但关键是应该有一种方法让它更快),我可能会建议你使用更高级别的Java2D游戏框架,如果你要走这条路(,),或者使用Slick2D(),也就是LWJGL(OpenGL)-基于:)主要的问题将是从每秒重新绘制整个游戏屏幕60次的速度。它很慢,但只需重新绘制脏区域即可加快速度。然而,对于新手来说这很复杂,而更高级别的libs可以为您做到这一点。