Java ConcurrentLinkedQueue 行为异常

Java ConcurrentLinkedQueue behaving oddly

我正在做一个项目,在这个项目中我将某些数据包添加到队列中以供稍后处理(接下来的 600 毫秒滴答处理队列中的所有数据包)。

但是,我目前遇到的问题是,当在同一周期内接收到两个数据包时,队列的行为非常奇怪。

在我的 class 顶部 我有

    private ConcurrentLinkedQueue<RSPacket> logicPackets;

public LogicDecoder() {
    super();
    logicPackets = new ConcurrentLinkedQueue<RSPacket>();
    addDecodeable(new SendWalk());
}

并添加我有的数据包

    @Override
public void decode(RSPacket packet, Session session) {
    GameServer.get().logger().debug("LogicDecoder decoded " +  packet.getId() + " - " + packet.getLength() + " - " + packet.getOffset());
    for (RSPacket p : logicPackets) {
        if (p.getId() == packet.getId()) {
            logicPackets.remove(p);
            GameServer.get().logger().debug("Removed packet from queue with id " + packet.getId());
            break;
        }
    }
    logicPackets.add(packet);
    for (RSPacket p : logicPackets) {
        GameServer.get().logger().debug("LogicDecoder containsOnDecode " + p.getId());
    }
}

这是调用解码的代码,这是decodeDecodables()方法的重要部分 注意:当我尝试不使用 getConvertedPacket()

时,同样的问题仍然出现
Decoder d = (Decoder) handler;
            P converted = (P) d.getConvertedPacket(packet, session);
            if (packet.getId() != PACKET.PING.getId()) {
                GameServer.get().logger().debug(packet.getId() + " -> " + converted.getId());
            }
            if (d.canHandle(converted, session) && d.preDecode(converted, session)) {
                d.decode(converted, session);
                return true;
            }

最后,这里是队列的最终使用方式:

    @Override
public void onTick(Session session) {
    super.onTick(session);
    //GameServer.get().logger().debug("We have " + logicPackets.size() + " logicPackets to process");
    for (RSPacket p : logicPackets) {
        GameServer.get().logger().debug("pending packet id: " + p.getId());
    }
    RSPacket packet;
    while ((packet = logicPackets.poll()) != null) {
        //GameServer.get().logger().debug("LogicDecoder onTick Poll " + PACKET.forId(packet.getId()).name());
        if (!preDecode(packet, session) || !decodeDecodeables(packet, session)) {
            decodeFail(packet, session);
        }
    }
}

这是将 ID 为 8 的数据包和 ID 为 59 的数据包背靠背发送时的输出。

[17:31:32] -> WorldDecoder recieved packet 8
[17:31:32] -> 8 -> 8
[17:31:32] -> LogicDecoder decoded 8 - 21 - 2
[17:31:32] -> LogicDecoder containsOnDecode 8
[17:31:32] -> WorldDecoder recieved packet 59
[17:31:32] -> 59 -> 59
[17:31:32] -> LogicDecoder decoded 59 - 21 - 12
[17:31:32] -> Removed packet from queue with id 59
[17:31:32] -> LogicDecoder containsOnDecode 59

如你所见,第一遍没问题,它把数据包8添加到队列中,然后当函数再次为数据包59调用时,它决定我们之前添加的数据包(数据包8)现在是数据包59 并在添加自身之前将其删除。老实说,我不知道这里发生了什么。

通过更改数据包 class 以实现 Cloneable,我能够修复此修改:

logicPackets.add(packet);

为此:

 logicPackets.add((RSPacket)packet.clone());