始终相同的线程获得CPU时间

时间:2013-08-22 04:10:33

标签: java multithreading synchronization

代码太大,所以我只会复制有问题的部分。

这是一个类中的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!");
}

}

这是星际迷航的模拟。可变团队代表船舶属于哪个团队。如果船在战斗中被摧毁或在移动时坠毁,则Varable isDestroyed为真。 isThereAnyShipsInTheArea() - 如果距离为1或2,则船只在范围内。 空间是矩阵白色尺寸[90] x [90]。

我认为问题在于run方法,但我会给你一些其他的方法。

    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;

  }

}

2 个答案:

答案 0 :(得分:0)

对我来说,你不应该做Thread.sleep(),因为它不会释放它抓取的任何资源。使用ScheduledExecutorService计划任务或在对象监视器上执行wait()和yield()。

答案 1 :(得分:0)

你的睡眠时间超出你的while(true)阻滞,所以你不是每次循环睡觉一次,而是先睡一次,然后进入紧绷的循环。

将睡眠放在while(true)块的末尾,这样您就可以在循环的每次迭代中睡一次。理想情况下,它应该在空间数组上发布同步之后。

实际上,全阵列扫描在寻找物品方面远非理想。可能想要查看保留项目列表。只是为了得到一个想法,一个1000x1000阵列,其中有20个项目(空间很大,大部分是空的),当你通过阵列时将需要1,000,000个检查,但如果你重新组织你的检查是基于项目,你可能只需1000或更少的支票即可逃脱。

例如,船舶清单:

for (Ship ship : ships) {
   if (!ship.engaged()) {
     ship.scanForEnemies();
   }
   if (ship.detectEnemies()) {
     ship.attack();
   }
}

可能只需要绕过十几艘或更少的船只,检查几百个地点。如果你想知道上面的代码是如何工作的,在我的例子中,船将用空间数组构造,它保留了对它的引用。