2016-04-26 127 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似乎是一个好的开始。