2016-12-26 45 views
0

我正在爲大學項目開發​​一個簡單的服務器 - 客戶端骰子游戲。遊戲限制是可以有無數玩家。我試圖創建他們的分數列表,但我不知道如何傳遞玩家數量,因爲每次連接下一個玩家時,服務器都會接受新的連接,所以我無法阻止下一個線程的啓動。java中的多線程 - 未知數量玩家的得分列表

我在想的東西,如「PLAY」按鈕/布爾變量在等待玩家和遊戲開始之後,下一個線程將無法獲得start.However,我不知道如何實現它。有什麼建議麼?另一個想法也將是一個很好的建議:)

下面是從服務器的代碼片段:

public void initializeResultList(int amountOfPlayers){ 
    final ArrayList<Object> resultDescription = new ArrayList(); 
    ArrayList<Object> zeros = new ArrayList(); 
    resultDescription.add("Player"); 
    resultDescription.add("One Pair"); 
    resultDescription.add("Two Pairs"); 
    resultDescription.add("Three of a kind"); 
    resultDescription.add("Full House"); 
    resultDescription.add("Four of a kind"); 
    resultDescription.add("Five of a kind"); 
    for (int j = 0; j < resultDescription.size(); j++){ 
     zeros.add(null); 
    } 
    resultList.add(resultDescription); 
    //fill with nulls, then there will be player Scores 
    for (int i = 1; i <= amountOfPlayers; i++){ 
     resultList.add(zeros); 
    } 

} 

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


    int portNumber = 444; 

    ServerSocket serverSocket = null; 


    try { 
     serverSocket = new ServerSocket(portNumber); 
    } catch (IOException e) { 
     e.printStackTrace(); 
     System.out.println("Error finding port"); 
     System.exit(1); 
    } 

    // program loop 
    do { 
     Server server = new Server(serverSocket.accept()); 

     //HERE IS THE PROBLEM! 
     server.initializeResultList(2); // here should be passed the amount 
     server.start(); 
    } while (true); 

} 

@Override 
public void run(){ 
    System.out.println("Connection accepted"); 
    System.out.println("Client has successfully connected"); 
} 

下面是從播放器類的代碼(這不是問題的權利,但也許你想知道服務器和播放器如何通信):

public static void main (String args[]) throws IOException { 
    //Connect to the server 
    Socket socket = null; 
    int portNumber = 444; 
    String str; 
    BufferedReader br = null; 
    BufferedReader input = new BufferedReader(new InputStreamReader(System.in)); 
    PrintWriter out = null; 

    try { 
     socket = new Socket(InetAddress.getLocalHost(), portNumber); 
     br = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
     out = new PrintWriter(socket.getOutputStream(), true); 
    } catch (UnknownHostException uhe) { 
     System.out.println("Unknown Host"); 
     System.exit(0); 
    } 


    boolean quit = false; 

    while (!quit) { 

     str = input.readLine(); 
     out.println(str); 
    } 


} 
+0

如果即時讀取您的問題,您可以等待,直到服務器遇到來自客戶端的某種信號以停止處理。即不要只發送原始數據到服務器,而是在服務器上附加一個頭字符串(類似'end-stream:false; data:yourstring'或'end-data:true; data:yourstring')並解析出來。那麼你不需要知道你傳遞的數字,因爲告訴線程何時停止處理是數據本身的一部分。考慮檢查光標模式。 –

+0

嗯,所以你的意思是客戶端做了一些操作,防止服務器連接到更多的線程?我沒有得到這個解決方案與標題字符串:( –

+0

嗯,我認爲你正在試圖處理的根本問題不是與多線程真的做。想想你怎麼可以發送或接收數據集你需要發送一些關於該集合的元數據,這樣你就知道它有多大,或者向服務器發送一個令牌,告訴它該數據集何時結束......實際上,你不需要在你的服務器上使用多線程,實際上,設置這麼多的線程在計算資源方面效率是非常低的 –

回答

0

有幾種可能的實現方式。一個想到的,包括隊列隊員。所以無論何時新玩家連接,它都會排隊等候,直到您的應用程序啓動它。可以將隊列大小添加到本地計數器以獲取玩家總數。在你拉下球員後,他已經離隊了。 例如,您可以通過以下方式初始化隊列:

Queue<YourObject> queue = new ConcurrentLinkedQueue<YourObject>(); 

我們拿起併發連接隊列,因爲它的屬性,你可以檢查here的。當新用戶加入,你可以把播放器的隊列:

queue.offer(myObject); 

,而在你的servlet,例如在每一輪或結束時,你需要新的球員,你可以撥打:

YourObject myObject = queue.poll(); 

,或者你可以得到的新球員叫號:

int nrNewPlayers = queue.size();

如果您需要播放器對象,其中還包含有關播放器本身的信息和統計信息,這是一個很好的解決方案。不過,如果你真的只需要玩家的總數,那麼隊列是矯枉過正,你可以只使用tomic integer在follwing方式:

//Initialize the integer in constructor 
public static AtomicInteger userCounter = new AtomicInteger(0); 

//Increment number of users when a new user is added() 
userCounter.incrementAndGet(); 

//Decrement the number of users when a user disconnects 
userCounter.decrementAndGet(); 

//Get number of users from within your code 
int counter = userCounter.intValue(); 

讓你的服務器代碼將是:

//HERE IS THE PROBLEM! 
int counter = userCounter.intValue(); 
server.initializeResultList(counter); // here should be passed the amount 

這是我可以用你提供的代碼做的最好的。如果您需要更多幫助,請創建一個新問題,並提供更多代碼而不是片段,並更好地說明您需要的內容。希望這會幫助你。

+0

究竟如何?也許一個簡單的例子?我應該使用哪個隊列?併發鏈接還是不同? –