【发布时间】:2013-08-22 04:10:33
【问题描述】:
代码太大了,我只复制有问题的部分。
这是一个类中的 run() 方法:
public void run(){
try{
sleep(1000);
while(true){
synchronized(space){
if(end)
return;
if(space[X][Y] == null)
break;
if(((Ship)space[X][Y]).isDestroyed){
destroy();
break;
}
if(isThereAnyShipsInTheArea() != 0){
if(team != ((Ship)space[X][Y + isThereAnyShipsInTheArea()]).team){
fight(isThereAnyShipsInTheArea());
}
}
else
move();
if(isDestroyed){
destroy();
break;
}
}
}
}
catch(InterruptedException ie){
System.out.println("Interrupted exception!");
}
}
这是星际迷航的模拟。可变团队表示该船属于哪个团队。如果船在战斗中被摧毁或在移动时坠毁,则变量 isDestroyed 为真。 isThereAnyShipsInTheArea() - 如果距离一到二,船就在范围内。 空间是维度为 [90]x[90] 的矩阵。
我认为问题在于运行方法,但我会给你一些其他方法。
private int isThereAnyShipsInTheArea(){
if(space[X][Y - 2] instanceof Ship && ((Ship)space[X][Y - 2]).isDestroyed == false)
return -2;
if(space[X][Y - 1] instanceof Ship && ((Ship)space[X][Y - 1]).isDestroyed == false)
return -1;
if(space[X][Y + 1] instanceof Ship && ((Ship)space[X][Y + 1]).isDestroyed == false)
return 1;
if(space[X][Y + 2] instanceof Ship && ((Ship)space[X][Y + 2]).isDestroyed == false)
return 2;
return 0;
}
private synchronized void fight(int meet){
while(((Ship)svemir[X][Y]).isDestroyed == false && ((Ship)space[X][Y + meet]).isDestroyed == false){
if(((Ship)space[X][Y]).getProjectile() != 0){
((Ship)space[X][Y + meet]).setShield(((Ship)space[X][Y + meet]).getShield() - 1);
((Ship)space[X][Y + meet]).setWarp(((Ship)space[X][Y + meet]).getWarp() - 1);
((Ship)space[X][Y]).setProjectile(((Ship)space[X][Y]).getProjectile() - 1);
if(((Ship)space[X][Y + meet]).getShield() == 0 || ((Ship)space[X][Y + meet]).getWarp() == 0){
((Ship)space[X][Y + meet]).isDestroyed = true;
return;
}
}
if(((Ship)space[X][Y + meet]).getProjectile() != 0){
((Ship)space[X][Y]).setShield(((Ship)space[X][Y]).getShield() - 1);
((Ship)space[X][Y]).setWarp(((Ship)space[X][Y]).getWarp() - 1);
((Ship)space[X][Y + meet]).setProjectile(((Ship)space[X][Y + meet]).getProjectile() - 1);
if(((Ship)space[X][Y]).getShield() == 0 || ((Ship)space[X][Y]).getWarp() == 0){
this.isDestroyed = true;
return;
}
}
if(((Ship)space[X][Y]).getProjectile() == 0 && ((Ship)space[X][Y + meet]).getProjectile() == 0)
return;
}
}
【问题讨论】:
-
您应该在
run方法的循环中使用Thread.yield或Thread.sleep,但在synchronized块之外... -
一段时间后,同一个线程总是得到时间,虽然还有其他正在运行的线程
-
如果你想要这样的模拟,你最好使用一个线程。如果您使用多个线程,锁定和同步的开销可能意味着您的程序速度较慢,而且如您所见,当然更难以预测。如果您使用一个线程,您可以准确地看到处理顺序。
标签: java multithreading synchronization