我正在用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));
}
}
答案 0 :(得分:3)
我知道这可能不是这个问题的真正答案,但是竞争条件可能存在问题。 我假设你正在尝试使用lazy / singleton模式,因为GUI类的构造非常昂贵而且你只需要一个实例。
现在,会发生什么?如果一个线程进入if
语句体,它会创建一个新的GUI
实例。在下一次分配之前,它会被调度程序暂停。
现在弹出另一个线程,看到_sharedInstance
仍为null并创建另一个GUI
实例(依此类推......)。
让我们假设只有两个线程。
第一个线程运行到结束,第二个线程继续运行,现在您有两个GUI类实例。没有人说未分配的GUI实例被破坏或被垃圾收集。
与最终使用并将GUI实例直接分配给_sharedInstance
相比,这可以解释50%的性能损失。
参见例如http://en.wikipedia.org/wiki/Singleton_pattern处的Java示例 双重检查锁定,内部类或枚举是您可以使用的方式。