Java BlockingQueue消息在线程之间存在滞后问题

时间:2014-06-15 04:41:59

标签: java multithreading sockets threadpool blockingqueue

我已经实现了一个带有线程池套接字的双人游戏。每个玩家都连接到自己的线程。我根据this文章添加了一个消息队列系统。

问题是消息滞后。第一个播放器的第一个响应按预期添加到messageQueue。但是第二个玩家没有通过调用poll()来接收它,它只接收null。 然后第二个玩家响应第二个玩家接收第一个玩家消息。我的目的是在他/她的回复之前将消息发送给第二位玩家。

我一定是犯了一些错误,或者我忽略了一些重要的概念。

你能帮我找到吗?

我的代码是这样的,有两个与此相关的类,GameRunnable.java和Game.java。我省略了一些代码来简化这个混乱。

在GameRunnable类中;

public static final Map<GamerRunnable, BlockingQueue<String>> messageQueues = new ConcurrentHashMap<>();
public static final Map<String, GamerRunnable> gameQueue = new ConcurrentHashMap<>();
private Game game;


public void run() {
    System.out.println
        (this.setGameInstance(clientSocket, readerIn, output) ? "OK": "FAILED");
    messageQueues.put(this, new ArrayBlockingQueue<String>(100));

    // If player 1
    this.game.initGame(this);

    // If Player 2
    this.game.initGame(this);
}

public static GamerRunnable getGameThreadByName(String name) {
    return gameQueue.get(name);
}

public String getName() {
    return this.name;
}

在Game.java中

public Game(Socket clientSocket, BufferedReader readIn, OutputStream output) {
    this.sockGamer = clientSocket;

    try {
        this.out = output;
        this.inGamer = readIn; 
    } catch(Exception e) {
        e.printStackTrace();
    }

    public void sendToGamer(String msg) {
        try {
            this.out.write((msg+"\n").getBytes());
            this.out.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

public void initGame(GamerRunnable game) {
    try {
        boolean messageLoop = true;

        String line1 = null;
        String line2 = null;

        while (messageLoop) {

            line1 = inGamer.readLine();

            if (line1 != null) {

                System.out.println("Gamer says: "+line1);

                GamerRunnable gamer2 = null;
                if (game.getName().equals("red")) {
                    gamer2 = GamerRunnable.getGameThreadByName("black");
                }
                else if (game.getName().equals("black")) {
                    gamer2 = GamerRunnable.getGameThreadByName("red");
                }

                if (gamer2 != null) {                       
                    System.out.println("Adding to Queue");
                    GamerRunnable.messageQueues.get(gamer2).offer(line1);
                }
            }

            line2 = GamerRunnable.messageQueues.get(game).poll();

            if (line2 != null) {
                //receiving from Queue
                System.out.println(line2);
                game.getGameInstance().sendToGamer(line2);      
            }
        }

1 个答案:

答案 0 :(得分:1)

由于网络延迟,您可能需要短暂的延迟才能等待第一条消息到达队列。请尝试使用poll(time, unit)。这将等待消息显示在队列中的指定时间。如果没有,它将返回null,如poll()现在。如果没有可用消息,用户可能不会注意到500毫秒到1秒的延迟。