[英]Unexplained Java shenanigans - possibly to do with threading?
我目前正在使用Swing GUI构建Java(Eclipse)中的Game of Life模拟器,作为大学项目的一部分。 除了一个小瑕疵之外,这是奇妙的 -
它适用于我的上网本,但不适用于我试过的任何其他PC。 这是在Ubuntu下。
一些结构轮廓 - 我有一个模型,一个视图和一个控制器。 我还没有正确定义模型,但我已经完成了View(GUI部分)并启动了Controller。 Controller由Main方法运行,然后Controller在单独的线程中创建View类并进入while循环。
View实现了一个“订单”队列,它是从用户输入,鼠标点击以及不是用户输入中获得的。 Controller在while循环的迭代中从队列中选取这些命令,并根据需要执行它们。
然而,虽然代码在我的上网本(最新版本,Java 1.6.0_20)上运行良好,但它不能在我的PC上运行(最新版本,Java 1.6.0_20)或大学PC(karmic,以前的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而不是返回一个Command(一个带有id(String),x,y(int)和value(int)的简单容器类)而返回一个Integer,则会出现同样的问题。 或其他任何东西。
嗯,这是一个多线程问题的经典案例,因为你从不同的线程调用视图和控制器。 假设您的命令容器未同步。
令人高兴的是,命令的更新是由一个线程完成的,但是其他线程没有注意到它,因为更新不在同步块内。 可以把它想象成两个线程处理不同的CPU缓存 - 当一个线程写入时,另一个线程没有看到它,除非它导致缓存被刷新到主存储器中 - 这只有在调用synchronized时才会发生。
更多信息: http : //gee.cs.oswego.edu/dl/cpj/jmm.html
快速解决方案:使用java.util.vector而不是LinkedList
我们需要更多信息。 commands
是什么类型的?
无论哪种方式,比繁忙等待(在while循环中旋转)更好的解决方案是使用某种等待/通知机制。 您问题的明显候选者似乎是BlockingQueue
(如ArrayBlockingQueue
或LinkedBlockingQueue
)。 此类型的检索方法将阻塞, 直到有可用的数据(命令),而不是要求您在有可用命令之前不断轮询。
例如
BlockingQueue<Command> commands = new LinkedBlockingQueue<Command>();
//...
//wait for the next element and then get it
while(!stop) {
Command nextCommand = commands.take();
//do something with nextCommand
}
更可能的是,您没有捕获或未正确处理的错误。 仔细检查您是否没有抛出异常。
此外,您尝试删除您认为不相关的程序部分,并确保它一直失败。 这将帮助您确定真正的根本原因。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.