1

コードが大きすぎるので、問題のある部分だけをコピーします。

これは、1 つのクラスの 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 は、船が戦闘で破壊された場合、または移動中に墜落した場合に true になります。isThereAnyShipsInTheArea() - 距離が 1 または 2 の場合、船は範囲内にあります。space は次元 [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;

  }

}

4

2 に答える 2

0

あなたの睡眠はwhile(true)ブロックの外にあるので、ループごとに 1 秒間眠る代わりに、1 回寝てからタイトなループに入ります。

ブロックの最後にスリープを配置しwhile(true)て、ループの反復ごとに 1 回スリープします。理想的には、スペース アレイで同期がリリースされた直後である必要があります。

実際、完全なアレイ スキャンは、アイテムを見つける上で理想的とは言えません。アイテムのリストを保持することを検討したい場合があります。アイデアを得るために、20 個のアイテムを含む 1000x1000 の配列 (スペースが大きく、ほとんどが空) は、配列を通過するときに 1,000,000 回のチェックが必要ですが、アイテムに基づいてチェックを再編成すると、おそらくわずか 1000 件以下のチェックで済みます。

たとえば、船のリスト:

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

数百の場所をチェックして、十数隻以下の船をループするだけでよい場合があります。上記のコードがどのように機能するか疑問に思っているなら、私の例では、船は参照を保持する空間配列で構築されていたでしょう。

于 2013-08-23T02:45:41.867 に答える
0

Thread.sleep() は、取得したリソースを解放しないため、実行しないでください。ScheduledExecutorService を使用してタスクをスケジュールするか、オブジェクト モニターで wait() および yield() を実行します。

于 2013-08-23T02:38:40.050 に答える