【问题标题】:How to make sure a thread gets the most recent variables modified by another thread?如何确保一个线程获得另一个线程修改的最新变量?
【发布时间】:2011-09-27 00:26:40
【问题描述】:

好的,所以我正在制作一个 2D 游戏,所有地图都以 2D 数组表示。我有这个巨大的方法可以根据地图中已有的内容修改地图。所以在实现功能一段时间后,FPS 降低了,所以我决定尝试使用多线程来提高速度(好东西,不是吗?)。

我创建了 3 个线程来完成这项工作,一个用于绘制和处理事件,一个用于更新地图的基础部分,另一个用于更新另一组变量。问题是,它会绘制,但当我启动所有 3 个线程时它不会更新。当我从绘画线程调用方法时,它会更新。我通过添加“System.exit(0);”测试了第一个更新线程在运行时,它没有启动,否则它会启动。我还尝试直接在更新线程的运行方法中手动更改地图的瓦片,但它什么也没做。所以我得出结论,运行被执行,变量被修改。所以我想,也许画家使用的变量不是更新的变量。

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

差点忘了提,Events(在有paint()方法的类中)修改了Map,这部分确实有效。

我不知道该怎么做,有人有想法吗?

【问题讨论】:

    标签: java multithreading


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

      • 我的术语很混乱。问题是paint方法没有绘制被update方法修改的变量,它似乎绘制了默认变量,或者同一个类中修改的变量
      • 另外,我不确定您的游戏是否足够复杂以保证多线程。此外,事件处理当然不需要单独的线程——这些通常是回调,因此您设置一个包含事件详细信息的结构并在主事件循环(可能是命令队列)中获取它。
      • Events 没有单独的线程,它们只是与paint() 方法在同一个类中。另外,您知道提高 2D 游戏性能的更好方法吗?我以 30 FPS 的速度运行,功能很少,所以它会变得迟钝。我见过类似的游戏比我在 C 语言中以 60 FPS 做的多 3 倍(我知道这不一样,但关键是应该有办法让它更快)
      • 如果你走这条路(interactivepulp.com/pulpcore13thmonkey.org/~boris/jgame),我可能会建议使用更高级别的 Java2D 游戏框架,或者使用 LWJGL(OpenGL)的 Slick2D(slick.cokeandcode.com) )-based :) 主要问题将是绘制速度,因为必须每秒重绘整个游戏屏幕 60 次。它很慢,但可以通过仅重绘脏区域来加快速度。但是,对于新手来说这很复杂,而更高级别的库可以为您做到这一点。
      猜你喜欢
      • 2014-12-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-09
      • 1970-01-01
      • 1970-01-01
      • 2015-02-18
      • 1970-01-01
      相关资源
      最近更新 更多