2010-09-28 55 views
1

好了,所以我有一個客戶端/服務器測試回事,我傳遞的整數playerID一個線程在那裏它給人的int值,以一個簡單的播放器對象,比1整數不會遞增?

public static void main(String[] args) throws IOException { 

     Vector<Player> player = new Vector<Player>(); 

     SlickServer ss = new SlickServer(); 
     ss.setVisible(true); 

     ServerSocket serverSocket = new ServerSocket(4444); 
     boolean listening = true; 

     Integer playerID = new Integer(0); 

     while(listening){ 
      ss.textArea.append("Waiting to connect with player: " + playerID.intValue() + "\n"); 
      new ClientThread(serverSocket.accept(), player, playerID, ss.textArea).start(); 
      ss.textArea.append("Waiting to connect with player: " + playerID.intValue() + "\n"); 
     } 

     serverSocket.close(); 
     System.exit(0); 
    } 

playerID增量這裏就是它的線程增加它:

public ClientThread(Socket acceptedSocket, Vector<Player> players, Integer playerID, JTextArea textArea){ 
     super("ClientThread"); 
     this.acceptedSocket = acceptedSocket; 
     this.players = players; 
     players.add(new Player(50,50, playerID.intValue())); 

     if(players != null) 
      System.out.println("Not Null: " + players.size()); 

     boolean b = false; 
     for(int i = 0; i < players.size(); i++){ 
      if(!b){ 
       if(players.get(i).id == playerID){ 
        me = players.get(i); 
        b = true; 
       } 
      } 
     } 

     playerID = new Integer(playerID.intValue() + 1); 
     this.textArea = textArea; 
    } 
+3

閱讀http://stackoverflow.com/questions/40480/is-java-pass-by-reference可能會給你一些見解,爲什麼這不做你的期望。 – 2010-09-28 17:14:41

+1

如果您想了解更多關於線程之間數據共享的信息,我會推薦Java Concurrency in Practice。總之,如果你沒有明確地設計變量來共享,你永遠不知道你得到了什麼。 – extraneon 2010-09-28 17:51:26

回答

7

new Integer創造這是不提供給呼叫者客戶線程方法中一個全新的Integer實例。

但是,你需要考慮的主要和客戶端線程之間的同步。

AtomicInteger playerID = new AtomicInteger(0); 
while (listening) { 
    ss.textArea.append("Waiting to connect with player: " + playerID.get() + "\n"); 
    new ClientThread(serverSocket.accept(), player, playerID, ss.textArea).start(); 
    ss.textArea.append("Waiting to connect with player: " + playerID.get() + "\n"); 
} 

class ClientThread { 
    public ClientThread(Socket acceptedSocket, Vector<Player> players, AtomicInteger playerID, JTextArea textArea) { 
    // etc. 
    playerID.incrementAndGet(); 
    // etc. 
    } 
} 

你需要考慮如何併發執行多個線程之間共享數據:這可以使用​​聲明爲整數平凡的對象或類,如java.util.concurrent.atomic.AtomicInteger如下來實現。這也適用於Vector<Player>JTextArea參數。你應該換行訪問使用synchronize陳述酌情playerstextArea對象。

+0

'ClientThread'不應該負責增加ID,句點。 – ColinD 2010-09-28 17:17:49

+0

因爲這不是他應該使用的問題的解決方案。顯然,他需要了解Java如何工作,但在這種情況下,他的問題的根源在於他正在接近如何以錯誤的方式增加其玩家ID並將責任放在錯誤的地方。 – ColinD 2010-09-28 17:23:50

+1

我真的不明白你爲什麼要做所有這些共享的數據同步的東西,當這是一個簡單的事情在變量定義的地方遞增。另外,如果僅在構造函數中增加,則不需要同步,而在單個線程中調用該構造函數。另外,即使需要同步也無濟於事,因爲你無法使用'SharedData'做一個原子增量......一個'AtomicInteger'會更好。 – ColinD 2010-09-28 17:41:16

0

嘗試使用IntHolder如果你需要它。

+2

AtomicInteger專爲這些情況而設計。 – extraneon 2010-09-28 17:52:01

2

增量main玩家ID創建ClientThread後。

客戶端線程不應該負責遞增玩家ID。這是main的責任,它是創建客戶端線程併爲其提供其ID的客戶端。

0

如果你想操縱你需要一個對象中封裝它的方法中的整數。

閱讀這篇文章,以更好地理解 http://www.javaworld.com/javaworld/javaqa/2000-05/03-qa-0526-pass.html

+2

Java不會通過引用傳遞對象。它通過值傳遞參考。有一個世界的不同。 – dty 2010-09-28 17:25:32

+0

謝謝@dty,我刪除了錯誤的細節。 – 2010-09-28 17:47:30