问题
作为大学项目的一部分,我目前正在半途中使用Swing GUI用Java(在Eclipse中)构建“生活游戏”模拟器。除了一个小缺陷外,这一切都是奇妙的-
它可以在我的上网本上使用,但不能在我尝试过的任何其他PC上使用。这是在Ubuntu下。
一些结构轮廓-我有一个模型,一个 View 和一个 Controller 。我还没有正确定义模型,但是我已经完成了View(GUI部分)并启动了Controller。 Controller由Main方法运行,然后Controller在单独的线程中创建View类,并进入while循环。
View 实现了它从用户输入,鼠标单击以及其他未收到的“订单”队列。 Controller 在while循环的迭代中从队列中挑选这些订单,并在必要时执行它们。
但是,尽管该代码在我的上网本(最新版本,Java 1.6.0_20)上正常运行,但在我的PC(再次为最新版本,Java 1.6.0_20)或大学PC(业力,Java的某些早期版本)上均无法运行)。一旦碰到“getNextCommand”方法,它就会停止。
没有错误,它只是拒绝打印/遵守
源文件位于此处-http://www.mediafire.com/?dfwtdkj1tdxd5xl
感兴趣的文件是Controller和View。
例子
在View中,我具有以下功能:
public Command getNextCommand() {
System.out.println(commands.getFirst().id);
return commands.pop();
}
不言而喻,当Controller调用getNextCommand()时,它会打印出原来的命令。这是Controller中的while循环:
while(!stop) {
if (gui.hasCommand()){
order = gui.getNextCommand();
//System.out.println("Something");
//if(order.id.equals("stop")) { stop = true; }
}
}
这很好。如您所愿,它将在getNextCommand中打印。取消注释这两个语句中的任何一个,它突然停止工作。不再为您打印!
为什么会这样?为什么这可以在我的上网本上工作,而不在我的PC上工作? :C
进一步说明
另外,如果我运行Eclipse生成的.class文件,它会打印(假设这两行都被注释掉了)。如果我自己使用javac进行编译,则不会显示任何内容。
任何见识将不胜感激!
谢谢,
卢克
编辑
如果在我调用getNextCommand时返回一个Integer而不是返回一个Command(一个具有id(字符串),x,y(int)和值(int)的简单容器类)而不是返回一个Command,则会出现相同的问题。或其他任何东西。
最佳答案
嗯,这就是多线程问题的典型案例,因为您从不同的线程调用 View 和 Controller 。假设您的命令容器未同步。
可能发生的情况是,命令更新是由一个线程完成的,但是另一个线程没有注意到它,因为更新不在同步块(synchronized block)内。可以将其视为在不同CPU缓存上工作的两个线程-一个线程写入时,另一个线程看不到它,除非它导致将缓存刷新到主内存中-并且仅在调用sync时才会发生。
更多内容:http://gee.cs.oswego.edu/dl/cpj/jmm.html
快速解决方案:使用java.util.vector代替LinkedList