我正在为Java class I TA制作编码游戏。游戏是在无向图上管理一队卡车(Truck extends Thread
),使用尽可能少的时间/燃料将包裹运送到各个目的地。学生扩展了一个抽象的经理课程,填补了卡车行为的空白(到达目的地后该怎么办等)。卡车类的运行方法是一个事件循环,它等待用户指令,然后在接收到旅行目的地时跟随它。这是事件循环:
@Override
/** The Truck's main running routine. While the travel directions are empty,
* Waits for more instructions in WAIT_TIME intervals. While the travel directions
* are not empty, pops off the next travel direction
*/
public void run(){
while(game.isRunning()){
setGoingTo(null);
while(travel.isEmpty() && game.isRunning()){
try{
Thread.sleep(WAIT_TIME);
}
catch (InterruptedException e){
e.printStackTrace();
}
setStatus(Status.WAITING);
game.getScore().changeScore(Score.WAIT_COST);
}
while(!travel.isEmpty() && game.isRunning()){
Edge r = getTravel();
try {
travel(r);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
第一个内部while循环循环,而没有要遵循的旅行说明。如您所见,每个WAIT_TIME毫秒(一帧),分数会减少等待成本 - 卡车空转的成本。 然而,我意识到,绕过这个成本的潜在解决方案的一种方法是告诉卡车(线程)在没有指令的情况下等待,然后在用户计算出指令后通知它。我想以编程方式阻止此操作,而不是仅仅按说明进行操作。
这甚至可能吗?也许是线程类中的一个方法要覆盖?是否可以阻止扩展Thread的类等待(在任何事情上?)如果卡车线程试图执行./(p),我会解决任何类型的异常。
感谢您阅读以及如何解决规则中的这一差距的任何建议!如果你想尝试一下,游戏很快就会在公众回购中出现。
答案 0 :(得分:1)
我没有针对您提出的确切问题(如何防止等待)提供解决方案,但建议对评论来说太长了:
如何测量第一个while循环开始到结束之间的时间。
long starttime = System.currentTimeMillis();
setStatus(Status.WAITING);
while(travel.isEmpty() && game.isRunning()){
try{
Thread.sleep(WAIT_TIME);
}
catch (InterruptedException e){
e.printStackTrace();
}
}
long endtime = System.currentTimeMillis();
long waittime = endtime - starttime;
game.getScore().changeScore(Score.WAIT_COST * (1 + waittime / WAIT_TIME));
即使线程被发送到睡眠状态,分数也会根据经过的时间而改变。您将无法获得实时游戏分数更新。
答案 1 :(得分:1)
我非常确定您无法阻止.sleep()
或.wait()
,因为您无法覆盖或篡改它们。所以唯一的方法是监控他们。
我不知道线程内部的方法,但是从线程外部(例如来自监视线程),您可以通过
获取线程状态Thread.getState()
如果有人在线程上调用sleep
或线程正在等待wait
调用,则结果应为Thread.State.TIMED_WAITING
。然后你必须确保的是,监听线程知道那些叫睡眠的学生而不是你(例如私人旗帜)。
监控线程当然可以采取任何你想要的反制措施,例如抛出异常或只是默默地解释点。
相关文档:
http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.State.html#TIMED_WAITING
http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#getState()
答案 2 :(得分:1)
我想知道每辆卡车的螺纹是否是正确的方法。您是否正在尝试教他们线程?或者您是否正在尝试向他们介绍图算法和启发式算法? (如果单一责任原则适用于家庭作业,那么答案应该是一个或另一个,但不能两者兼而有之。)
如果重点是算法和启发式,那么我会编写一个单线程程序,其中主循环执行一系列“移动”。在每次移动中,它会询问每个卡车对象下一步卡车要做什么,然后它会相应地移动卡车,或者如果卡车要求做一些没有意义的事情,它会将分配标记为无效
在我的版本中,模拟中的“时间”将与实时完全分离,因此如果某个学生在其策略例程中放入Thread.sleep(),则不会对结果产生任何影响该计划;它只会使程序运行时间更长。 (当然,我会在一个批处理脚本的控制下运行它们,这些脚本会中止任何花费超过...比如三分钟的任务。)