简体   繁体   中英

Always the same thread gets CPU time

Code is too large, so I'll just copy the part that is problematic.

This is run() method in one class:

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!");
}

}

This is simulation of Star Trek. Variable team represends to which team the ship belongs. Varable isDestroyed is true if the ship is destroyed in battle or crash when moving. isThereAnyShipsInTheArea() - ship is within range if the distance one or two. space is matrix whit dimensions [90]x[90].

I think problem is in run method, but I'll give you some other methods.

    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;

  }

}

To me you shouldn't do Thread.sleep() since it doesn't release any resources it grabs. Either schedule your task using ScheduledExecutorService or do wait() and yield() on an object monitor.

Your sleep is outside of your while(true) block, so instead of sleeping for a second every loop, you sleep once and then go into a tight loop.

Put the sleep at the end of the while(true) block, so you sleep once for every iteration of the loop. Ideally it should be just after the release of the synchronization on the space array.

Actually, full array scanning is far from ideal on finding items. Might want to look into keeping lists of items. Just to get an idea, a 1000x1000 array that has 20 items in it (space is big and mostly empty) will take 1,000,000 checks as you pass over the array, but if you reorganize your checks to be base on the items, you could probably get away with just 1000 or less checks.

For example, a list of ships:

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

might only have to loop through a dozen or fewer ships, checking a few hundred locations. If you are wondering how the above code works, in my example, the ship would have been constructed with a space array, that it kept a reference to.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM