首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >总是同一个线程获得CPU时间

总是同一个线程获得CPU时间
EN

Stack Overflow用户
提问于 2013-08-22 12:10:33
回答 2查看 128关注 0票数 1

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

这是一个类中的run()方法:

代码语言:javascript
复制
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!");
}

}

这是“星际迷航”的模拟。Variable team表示该船所属的团队。如果舰船在战斗中被摧毁或在移动时坠毁,则可变isDestroyed为真。isThereAnyShipsInTheArea() -如果距离为1或2,则船在范围内。空间是维度为90x90的矩阵。

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

代码语言:javascript
复制
    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;

}

代码语言:javascript
复制
 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;

  }

}

EN

回答 2

Stack Overflow用户

发布于 2013-08-23 10:38:40

对我来说,您不应该使用Thread.sleep(),因为它不会释放它所获取的任何资源。可以使用ScheduledExecutorService调度任务,也可以在对象监视器上执行wait()和yield()。

票数 0
EN

Stack Overflow用户

发布于 2013-08-23 10:45:42

您的睡眠在while(true)块之外,所以不是每个循环睡眠一秒钟,而是睡眠一次,然后进入一个紧凑的循环。

将休眠放在while(true)块的末尾,这样循环的每次迭代都会休眠一次。理想情况下,它应该正好在空间阵列上的同步释放之后。

实际上,全数组扫描在查找项目方面远非理想。可能需要考虑保存物品清单。仅需了解一下,一个包含20个项目的1000x1000数组(空间很大,大部分都是空的)将在您遍历该数组时接受1,000,000个检查,但是如果您将检查重新组织为基于这些项目,则可能只有1000个或更少的检查。

例如,船舶列表:

代码语言:javascript
复制
for (Ship ship : ships) {
   if (!ship.engaged()) {
     ship.scanForEnemies();
   }
   if (ship.detectEnemies()) {
     ship.attack();
   }
}

可能只需要循环通过十几艘或更少的船,检查几百个位置。如果你想知道上面的代码是如何工作的,在我的例子中,船应该是用一个空间数组构造的,它保留了一个引用。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18371554

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档