Java ConcurrentLinkedQueue没有';按预期工作

Java ConcurrentLinkedQueue没有';按预期工作,java,android,Java,Android,我正在开发一个Andoid应用程序,它由一个在后台运行的服务和一些连接到该服务的活动组成。该服务在自己的进程上运行 我的服务主要有三类:ServiceMain、ServiceWorker、Message ServiceMain具有登录、注销、发送等活动所使用的所有功能。。。等等 Message表示发送到服务器或接收到的消息。只需一个字符串和一个bool,其中字符串是消息,bool是表示是否需要服务器响应的标志 ServiceWorker是Thread的一个子类,它使用套接字发送和接收消息 Ser

我正在开发一个Andoid应用程序,它由一个在后台运行的服务和一些连接到该服务的活动组成。该服务在自己的进程上运行

我的服务主要有三类:ServiceMain、ServiceWorker、Message

ServiceMain具有登录、注销、发送等活动所使用的所有功能。。。等等

Message表示发送到服务器或接收到的消息。只需一个字符串和一个bool,其中字符串是消息,bool是表示是否需要服务器响应的标志

ServiceWorker是Thread的一个子类,它使用套接字发送和接收消息

ServiceMain包含2个队列:

Queue<Message> Sendingqueue= new ConcurrentLinkedQueue<Message>(); 
Queue<Message> Recievequeue = new ConcurrentLinkedQueue<Message>();
Queue Sendingqueue=new ConcurrentLinkedQueue();
Queue ReceiveQueue=新建ConcurrentLinkedQueue();
如果登录方法被调用,则创建并启动ServiceWorker。在它的构造函数中,它获取对这两个队列的引用并保存它们

private final Queue<Message> Sendingqueue;
private final Queue<Message> Recievequeue; 
专用最终队列发送队列;
私有最终队列receivequeue;
ServiceMain然后创建一些消息(例如M1、M2)并将它们添加到发送队列中

ServiceWorker建立到服务器的连接,然后运行到一个循环中,在该循环中,它在Sendingqueue中查找消息,发送消息,并执行其他一些操作,如接收

希望情况现在清楚了

在ServiceWorker中,Sendingqueue上发生了一些奇怪的情况:

假设ServiceMain在ServiceWorker执行耗时的操作或未连接到服务器时向Sendingqueue添加了两条消息M1和M2。 Sendingqueue现在包含两条消息

如果ServiceWorker下次获得队列的长度,它将看到2个项目。好的,到目前为止。 然后,它在Sendingqueue上调用peek()(只有在成功发送消息时才会删除该消息),并且应该获取M1,因为它是首先添加的。 但它得到了M2。 发送队列似乎已还原

这里怎么了?我能做些什么来避免这种情况

谢谢你的建设性回复


Detlef

ConcurrentLinkedQueue不保证顺序,但如果您将元素添加到末尾并从一开始(或visa从一开始)使用thsi,则元素的顺序不应改变。如果从开始或结束添加和删除,可能会遇到问题,因为这意味着每次处理的都是最新的,而不是最旧的

如果您有一个功能强大的大型服务器,我仍然认为这种方法是过分的。我将使用主线程而不是后台线程来执行处理


注意:套接字在客户端和服务器上已经是一个输入和输出队列,因此添加第三层队列在大型系统中可能是多余的,在小型设备中可能效率低下。

我刚刚阅读了,它似乎可以保证:队列的头是在队列上时间最长的元素。队列的尾部是在队列中出现时间最短的元素。如果“队列”不能保证顺序,“队列”将毫无用处。它甚至不符合它的名字!两个并发运行的线程几乎同时添加到队列中,无法保证哪个线程将首先添加。一旦添加了订单,就应该保证订单。您是对的,oers和BeeOneRope,队列应该保证订单。先进先出。但在我的情况下,它不是,或者是,但它恢复了顺序。我之所以把发送和接收放在自己的线程中,是因为如果没有可用的网络,服务不应该阻塞。每个线程只写入其中一个线程。ServiceMain写入Sendingqueue并从ReceiveQueue读取,ServiceWorker从Sendingqueue读取并写入ReceiveQueue。请尝试提供一个示例,因为仅从散文很难看出您做错了什么。你确定你是在增加尾巴和从头部偷看,还是相反?我将试着做一个例子来重现这一点。