2016-04-26 128 views
0

我正在將我的python websocket遊戲服務器升級到Java(使用Jetty for websockets),並且最近開始瞭解線程安全性。Java遊戲服務器線程安全接收網絡套接字消息

我的挑戰是,遊戲邏輯(gameRoom實例)主線程上運行,但服務器將收到玩家的信息(例如,消息加入遊戲室),並通知遊戲邏輯FROM ANOTHER螺紋。我最初(在Python中 - 當所有主線程都在)時,我馬上處理了這條消息(例如,添加一個玩家接收消息)。這可能會導致多線程問題,因爲遊戲室線程可能會同時向玩家陣列添加玩家。 (球員名單最終加入了玩家=不是線程安全的過程中被共享!)

什麼是處理來自它自己的線程中運行一個servlet recieving消息最簡單的方法,以及處理這些消息不會弄亂遊戲的運行在主線程(不同的線程)?在我的腦海中,我會想象某種單向緩衝區(例如http://web.mit.edu/6.005/www/fa14/classes/20-queues-locks/message-passing/)排隊新消息,以便在邏輯的一部分期間僅由gameRoom自己處理。或者有沒有辦法避免多線程? *請給出你的想法,我很樂意聽到一個比我的初級知識水平更高的人。我非常感謝所有的提示/建議:) *

我花了時間,使顯示發生了什麼事情一個簡單的例子(請忽略synax錯誤,我做到了超短您舒適:)):

class ServerClass { 
    static GameRoomClass gameRoom; 


    static void main() { 
     //psuedocode start Jetty Server, this server runs in another thread, will call onServerMessage() 
     jettyServer.start(); 
     jettyServer.onMessageCallback=(onServerMessage); //set message callback (pseudocode) 

     //create game room, run on main thread 
     gameRoom = GameRoomClass(); 
     gameRoom.runGameRoom(); 
    } 

    //when the server gets a message from a player, 
    //this will be called by the server from another thread, will affect the GameRoom 
    static void onServerMessage(Message theMessage) { 
     gameRoom.gotServerMessage(); 
    } 
} 

//this runs game logic 
class GameRoomClass { 
    ArrayList<E> players = new ArrayList<>(); 

    public void runGameRoom() { 
     while (true) { 
      //move players, run logic... 

      //sometimes, may call addNewPlayer AS WELL 
      if(...){ 
       addNewPlayer(); 
      } 
     } 

    } 

    public gotServerMessage(){ 
     //this will only be called by the 'Server' thread, but will enter 'addNewPlayer' method 
     //meaning it will access shared value players? 
     addNewPlayer() 
    } 

    public addNewPlayer(){ 
     //this will be called by the server thread, on getting a message 
     //can ALSO be called by gameRoom itself 
     players.add(new PlayerObj()); 
    } 

} 

class PlayerObj { 
    //a player in the game 
} 

回答

1

最簡單有效的方法是使用java.util.concurrent包中的一個線程安全的集合類。 對於給定的情況,ConcurrentLinkedQueue似乎是一個好的開始。