2013-08-22 53 views
1

代碼太大,所以我只是複製有問題的部分。總是同一個線程獲得CPU時間

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

}

這是星際旅行的仿真。可變團隊代表船屬於哪個團隊。如果艦船在戰鬥中被摧毀或在移動時發生墜毀,那麼可摧毀的物品是真實的。 isThereAnyShipsInTheArea() - 如果距離爲1或2,則船舶在範圍內。 空間是矩陣白色尺寸[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; 

    } 

}

+0

你應該''Thread.yield'或'Thread.sleep'在'run'方法的循環中,但在'synchronized'塊的外側... – MadProgrammer

+1

問題是什麼? –

+0

過了一段時間,同一個線程總是獲得時間,雖然還有其他正在運行的線程 – szeljic

回答

0

對我來說,你不應該做的Thread.sleep(),因爲它不釋放它抓住的任何資源。請使用ScheduledExecutorService安排您的任務,或者在對象監視器上執行wait()和yield()。

0

你的睡眠超出了你的while(true)區塊,所以你不要每睡一秒鐘就睡一次,然後進入緊張的循環。

將睡眠放在while(true)塊的末尾,因此每循環一次就睡一次。理想情況下,它應該是在空間陣列上發佈同步之後。

實際上,全陣列掃描在尋找物品方面遠非理想。可能想查看保存物品清單。爲了得到一個想法,一個包含20個項目的1000x1000陣列(空間很大,大部分都是空的)在您通過陣列時將需要1,000,000個支票,但是如果您將支票重新組織爲基於項目,您可能可能只需1000或更少的支票即可離開。

例如,船舶的列表:

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

可能只需要通過一打或更少的船隻環路,檢查幾百個位置。如果你想知道上面的代碼是如何工作的,在我的例子中,這艘船就是用一個空間數組構建的,它保留了一個引用。

相關問題