6

我正在用java编写一个简单的游戏。我用 30 FPS 进行了碰撞测试,我必须得到窗口的大小。因为我无法访问 GUI 实例,所以我想我会创建一个共享实例,因为这在我来自的 Objective-C 中是相当标准的。

class GUI extends JFrame {
    private static GUI _sharedInstance;

    public static GUI sharedInstance() {
        if (_sharedInstance == null) {
            _sharedInstance = new GUI();
        }
        return _sharedInstance;
    }
}

但由于某种原因,它真的很慢。然后我用大小的实例替换了共享实例public static final,它现在工作得很快,即使是 60 FPS 或更高。

谁能解释我为什么会这样?

编辑

所以GUI.sharedInstance().getWidth()我没有打电话,而是打电话GUI.windowSize.width。我已经使用了public static final Dimension windowSize

编辑

这是碰撞检测。所以,int width = GUI.kWindowWidth;int width = GUI.sharedInstance().getWidth();之前没有打电话,而是打电话。

// Appears on other side
if (kAppearsOnOtherSide) {
    int width = GUI.kWindowWidth;
    int height = GUI.kWindowHeight;

    // Slow
    // int width = GUI.sharedInstance().getWidth();
    // int width = GUI.sharedInstance().getHeight();

    Point p = this.getSnakeHead().getLocation();
    int headX = p.x;
    int headY = p.y;

    if (headX >= width) {
        this.getSnakeHead().setLocation(new Point(headX - width, headY));
    } else if (headX < 0) {
        this.getSnakeHead().setLocation(new Point(headX + width, headY));
    } else if (headY >= height) {
        this.getSnakeHead().setLocation(new Point(headX, headY - height));
    } else if (headY < 0) {
        this.getSnakeHead().setLocation(new Point(headX, headY + height));
    }
}
4

1 回答 1

3

我知道这可能不是问题的真正答案,但竞争条件可能存在问题。我假设您正在尝试使用惰性/单例模式,因为 GUI 类的构建非常昂贵,并且您只需要一个实例。

现在,会发生什么?如果一个线程运行到if语句体中,它会创建一个新GUI实例。就在下一次分配之前,它被调度程序暂停。现在另一个线程弹出,看到它_sharedInstance仍然为空并创建另一个GUI实例(等等......)。

让我们假设只有两个线程。第一个线程运行到最后,第二个线程继续运行,现在您有了 GUI 类的两个实例。没有人说未分配的 GUI 实例被破坏或垃圾收集。这可以解释与使用 finally 并将 GUI 实例直接分配给_sharedInstance.

参见http://en.wikipedia.org/wiki/Singleton_pattern上的 Java 示例 双重检查锁定、内部类或枚举是您可以使用的方式。

于 2012-11-23T01:35:31.653 回答